1. Trang chủ
  2. » Công Nghệ Thông Tin

Giáo trình C# 2005 - Tập 4, Quyển 2: Lập trình cơ sở dữ liệu, report, visual sourcesafe 2005 (Phần 2)

197 6 0
Tài liệu được quét OCR, nội dung có thể không chính xác

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 197
Dung lượng 33,73 MB

Nội dung

Nối tiếp phần 1, phần 2 của Giáo trình C# 2005 - Tập 4, Quyển 2: Lập trình cơ sở dữ liệu, report, visual sourcesafe 2005 tiếp tục cung cấp cho học viên các kiến thức về đối tượng DataGridView và ADO.NET, làm việc với Report và Crystal Report, làm việc với Visual SourceSafe 2005, Visual Studio 2005 và Visual SourceSafe 2005, ứng dụng quản lý nhân sự và tiền lương,... Mời các bạn cùng tham khảo chi tiết nội dung giáo trình!

Trang 1

Atri SourceSafe 2005

Trang 2

Chương 4: Đối tượng DataGridView và ADO.NET 173 [MỊ° Chương 4: ĐỐI TƯỢNG DATAGRIDVIEW VÀ ADO.NET Tóm tắt chương 4

Trong những chương trước, bạn đã tìm hiểu cách khai báo

uò sử dụng điều khién DataGridView dé trinh bày dữ liệu từ đối

tượng DataSet, DataTuble uà DataVieu

Trong chương này, bạn sẽ tiếp tục tìm hiểu cách trình bày

dữ liệu dưới nhiều hình thức từ đối tượng DataSet, DataToble, DataView bang déi tugng DataGridView, BindingSource và BindingNavigator Các uấn đề chính sẽ được đề cập: v_ Đối tượng DataGridVieu + Giới thiệu “% Thuộc tính s* Biến cố

Thêm điều khiển khúc uào DataGridView Đối tượng BindingSource

Đối tượng BindingNauigdtor

SPN

EES

Khai báo phương thức sử dụng chung

1 ĐỐI TƯỢNG DATAGRIDVIEW

Déi tugng DataGridView dùng để trình bày dữ liệu có trong đối tượng

DataSet, DataTable, DataView duéi hình thức khác nhau

Ngoài ra, bạn có thể định nghĩa các cột trên điểu khiển

Trang 3

Chương 4: Đối tượng DataGridView và ADO.NET

1.1 Thuộc tính

Trong những chương trước, chúng ta đã làm quen với thuộc tính

DataSource ding để điền dữ liéu.tu déi tugng DataSet, DataTable, DataView vao diéu khién DataGridView

1.1.1 Thuéc tinh DataSource

Để sử dung thuéc tinh DataSource, ban khai bdo doan chuong trình dé goi phuong thie FillDataSet trong lép Databases va dién di tugng DataSet vao diéu khién DataGridView nhu vi du 4-1

i du 4-1: DataGridView va DataSet

private void buttonl_Click (object sender, EventArgs e)

{

DataSet dataSet =cls.FillDataSet ( "select * from tblContracts",

CommandType Text) ;

L1 Khai báo gán đối tượng DataSet uà thuộc tính // DataSource ctia DataGridView

dataGridView1.DataSource =

dataSet.Tables[0]; ;

}

Khi thực thi, ban nhan vao nut DataSet thì dữ liệu trong bảng

Trang 4

Chương 4: Đối tượng DataGridView và ADO.NET 175 Tương tự, bạn có thể gọi phương thức #i11DatzTable từ lớp Databases để điển đối tượng Dœz7abie vào đối tượng DœiaGridVieu như ví dụ 4-2

i du 4-2: DataGridView va DataTable

private void button2_Click(object sender, EventArgs e) DataTable dataTable = cls FillDataTable(

"select FirstName, LastName, C.* from "+

" tblEmployees E, tblEducations C where "+ " E.EmployeeID=C.EmployeeID",

CommandType.Text) ;

// Khai bdo gan déi tuong DataTable va thuéc tinh // DataSource ctia DataGridView

dataGridViewl DataSource = dataTable;

}

Khi thực thi, bạn nhấn vào nút Dœ¿ơTœbie thì dữ liệu trong bảng

tblEmpioyees và tbÌEducdtions của cơ sở dữ liệu HRSQL trình bày như

hình 4-2

i { LastName EducationID| School DTY-00014 | Hao 1 HEMU of Econo Ton That Van DTY-00014 | Hao University of Nat Le Van Tri Van DTY-00018 | Dung HCMU of Techn Nguyen Thanh 'DTY-00020 iTu HCMU of Econo - JLeVan DTY-33064 | Anh Polytechnic Univ Le Quoc Van ADM-00036 | Hie Polytechnic Univ

Hinh 4-2: Trinh bay di liéu tu déi tuong DataTable

Ngoài ra, bạn có thể sử dụng đối tugng DataView để trích lọc dữ liệu

Trang 5

Chương 4: Đối tượng DataGridView và ADO.NET : DataGridView và DataView| private void button3_Click(object sender, EventArgs e) {

DataTable dataTable =cls.FillDataTable(

"select FirstName, LastName, C.* from" +

"tblEmployees E, tblExperiences C where"+ ˆ" E.EmployeeTD=C EmployeeTD", CommandType.Text) ; 11 Khai báo va khéi tao déi tuong DataView DataView dataView = new DataView(dataTable) ;

/I Khai báo gán đối tượng DataVieu uò thuộc tính L1 DataSource ctia DataGridView

dataGridViewl DataSource = dataView;

}

Néu ban nhdn vao ntt DataViewe thì dữ liệu trong bảng tblEmployees và tblEducations cua cơ sở dữ liệu HRSQL trình bày như

hình 4-3

FirstName: ie

DTY-00014 HCMU oÍ Econo Ton That Van DTY-00014 University of Nat LeVanTri Van | DTY-00018 HCMU of Techn Nguyen Thanh | DTY-00020 HCMU of Econo Le Van DTY-33064 Polytechnic Univ Le Quoc Van ADM-00036 | Hi Polytechnic Univ

Hình 4-3: Trình bày dữ liệu từ đối tueng DataView

Luu ý, trong ba ví dụ trên chúng ta có sử dụng biến c/s, bạn cần khai báo và khởi tạo déi tugng Databases trong bién cé Load cia Form nhu vi du

Trang 6

Chương 4: Déi tugng DataGridView va ADO.NET 177

i du 4-4: Khai bao va khéi tao déi tugng Databases

L1 Khai bdo déi tugng Databases Databases cls;

private void frmDataView_Load ( object sender, EventArgs e)

{

// Khéi tao déi tugng Databases cls = new Databases ();

1.1.2 Thuéc tinh CurrentRow

Để lấy ra mẩu tin đang chọn trên điều khiển DataGridView, ban có thể sử dụng thuộc tính CurrentRow Thuéc tinh CurrentRow tra vé déi tuong DataGridViewRow chtta dung mau tin dang chon nhu vi du 4-5

i du 4-5: Khai bao sw dung thuéc tinh CurrentRow

Trang 7

[MỊ? 1:s Chương 4: Đối tượng DataGridView và ADO.NEÉ

Thi thực thi chương trình, nếu bạn chọn một mẩu tin nào đó trên điều khiển DataGridView réi nhan nit CurrentRow thi két qua trinh bay nhu

hinh 4-4

"_CurtertFiow Propety: ADM-00022.Dinh Tien Van Sinh

soe Et Lastname -

Dinh Tien Van |Sih ADM-00028 |TatVinh Thi |HueThuơng ADM.00031 [Pham Ngoe Van |Long

g

TRIEEbissis-

ADM-00036 |Le Quoc Van |Hiep ADM-00038 [Dang Thuy Thi

S1 |ADM-00042 | Nguyen Quoc V | Sy

-|ADM-00047 | Mai Hoang Van Nam

IO

eS

e280

Da naaec+ bat ve Th? keene

Cunertow ] [CurentCet_} [ColumnCount and Rows Count Hình 4-4: Sở dụng thuộc tinh CurrentRow 1.1.3 Thuộc tính CurrentCell Trong trường hợp lấy giá trị trên ô đang chọn, bạn sử dụng thuộc tính CurrentCell như ví dụ 4-6

í dụ 4-6: Khai báo sử dụng thuộc tính CurrentCell

private void button3_Click(object sender, EventArgs e) {

DataGridViewCell dataGridViewCell = đataGridView1.CurrentCe11;

label1.Text = "CurrenERow Property: "+

Convert ToString (dataGridViewCell.Value) ;

Néu ban nhan vao nuit CurrentCell thì kết quả trình bày giá trị của, ô đang chọn tương tự như hình 4-5

Trang 8

Chương 4: Đối tượng DataGridView và ADO.NET 179 |MỊ [frmProperties]

Curentfiow Property: Dang Thuy Thi

EreloyealD Fistnane | Lastname Foreigner Gender ‘ADM-00022 [Dinh Tien’ Van | Sinh ole

‘ADM-00028 | Tat Vinh Thi HueThuong =f] | ] `

|ADM00031 |PhamNgoc Van tong sss) | E; ADM-00036 |Le Quoc Van | Hiep o | oa] > | ADM.00038 Diem Anh Oo

_{ADM-00042 |Nowen Quee V Sy o | o

‘ADM-00047 |MaiHoangVan |Nam o | o S1 ml Ta « Z (curentow _] [_CureniCet_] ( CokmnCount and Rows Count _] Logged by ADMINISTRATOR

Hinh 4-5: Si dung thuéc tinh CurrentCell

i du 4-7: S6 c6t va hang dif liéul

private void buttoni_Click (object sender, EventArgs e)

labell.Text = "ColumnCount Property: "+

Convert.ToString (dataGridView1l.ColumnCount) ; labell.Text += "-Rows.Count Property: "+

Convert ToString (dataGridViewl.Rows.Count) ;

} 3

Nếu bạn nhấn vào nút ColumnCount and Rows.Count thi két qua

trinh bay nhu hinh 4-6

ColumnCount Property: 16-Rows Count Property: 248

| Employee!D ( Firstname “Lastname Foreignet

> Dinh Tin Van Sinh o | ADM-00028 TaVnhTh |Hue Thuong —_ la] | _ |ADM-00031 Pham Ngoc Van _ 'Long D -_ |ADM-00036 LeQuec Van jHẹp o _{ADM-00038 Dang Thy Thi Diemanh | SE] ADM-00042 Nguyên Qược V Sy H_

ADM00047 |MaHomgVm (Nam Be:

Trang 9

(al 180 Chương 4: Đối tượng DataGridView và ADO.NET

1.2 Biến cố

Ngoài một số thuộc tính vừa trình bày ở trên, bạn có thể tìm hiểu một số biến cố thường sử dụng như: SelectionChanged, DoubieCiick

1.3.1 Biến cố SelectionChanged

Biến cố SelectionChanged xảy ra khi người sử dụng di chuyển con nháy thuộc hàng dữ liệu đang trình bày trên điều khién DataGridView

Để làm điều này, bạn khai báo đoạn chương trình trong biến cố

SelectionChanged dé trình bày mã, họ và tên nhân viên như ví dụ 4-8 í dụ 4-8: Khai báo sử dụng b private void dataGridViewl_SelectionChanged (object sender, EventArgs e) { DataGridViewRow dgViewRow = dataGridView1 CurrentRow;

labell.Text = "CurrentRow Property: "+

Convert ToString (dgViewRow.Cells[0].Value) THẺ dc

Convert.ToString (dgViewRow.Cells[1].Value)

+Convert.ToString (

dgViewRow.Cells[2].Value) ;

} :

Khi thực thi chương trình, nếu bạn di chuyển con chuột hay con nháy

trên từng hàng dữ liệu của điều khiển Dœ/œGridVieu thì mã, họ và tên

nhân viên trình bày như hình 4-7 ataGridView - [frmProperties]

CurentPiow Property: ADM-00047 Mai Hoang Van Nam

EnployeelD Firstname Lastname | Foreigner

‘ADM-00022 Dinh Tien Van thi 4 eee Bl ADM-00028 | TatVinh Thi Hue Thuong "TE

Pham Ngọc V: Van Long —_ oO

“TLeQuoc Van H TP Reed

'Dang Thuy Thi ñ 1

k a

> LU =

= > S a (_GurertCet_) [_CotsmnCount and Rows Count }

Logged by ADMINISTRATOR Soe

Trang 10

Chương 4: Đối tượng DataGridView và ADO.NET

1.2.2 Bién c6 DoubleClick

Trong trường hợp người sử dụng Doubie-Click trên điều khiển DataGridView, ban cé thé stt dung bién cé DoubleClick-nhu ví dụ 4-9

i du 4-9: Khai báo sử dung bién cé DoubleClick

private void dataGridViewl_DoubleClick(object sender, EventArgs e)

{

DataGridViewRow dgViewRow =

dataGridViewl.CurrentRow;

labell.Text = "DoubleClick Event: "+

Convert ToString (dgViewRow.Cells[0].Value) +

wom yg 5

Convert ToString (dgViewRow.Cells[1].Value) + Convert ToString (dgViewRow.Cells[2].Value) ;

Nếu bạn chon vao titng 6 trén diéu khién DataGridView réi Double-Click thi giá trị của ô đó trình bày như hình 4-8

& DataGridView - [frmProperties]

DoubleClick E vent: ADM-00038-Dang Thuy Thi Diem Anh 'EmployealD | Firstname Lastname -— |ApM-00022 Dinh Tien Van Sinh —_ [aow-ooma Tat Vinh Thi Hue Thuong — |ADM-00031 Pham Ngoc Van |Long

ADM-00036 LeQuoc Van |ADM-00038 Dang Thuy Thi | ADM-00042 Nguyen Quoc V

| ADM-00047 Mai Hoang Van J ADk4 nonc+ Nano TEEE TPk eae sui Si {_ curenttow ][_ Cưencel ][_ CawwCountandRowsComi } Hình 4-8: Sử dụng biến cố DoubleClick

2 THÊM ĐIỀU KHIỂN VÀO DATAGRIDVIEW

Trang 11

(A? ise Chương 4: Đối tượng DataGridView và ADO.NET

Khi lam viéc vi diéu khién DataGridView trong C# 2005, ban cé thé thém diéu khién nhu: Button, TextBox, ComboBox, Image, Link hay CheckBox vao diéu khién DataGridView rất dễ dàng

Khi thêm điều khiển Button, TextBox, ComboBox, Image, Link hay CheckBox vao diéu khién DataGridView, ban có thể thực hiện bằng trực quan hoặc viết mã

Chẳng hạn, bạn chọn điều khiển DataGridView rồi R-Click | Add Colưmn | rồi thêm cột như hình 4-9 Paneer Cay

Hình 4-9: Thêm cột uào điều khién DataGridView

Khi thêm cột dit liéu vao diéu khién DataGridView thi cot nay dang ở dạng không nhúng cột dữ liệu, sau đó bạn có thể điều chỉnh thuộc tính của cột bằng cách khai báo thuộc tính DaføPropertyNưrne bằng cách R-Click I Edit Columns

Luu y, méi Cell trén diéu khién DataGridView được xem như điều khién TextBox méi khi ban thém diéu khién khde vao diéu khién DataGridView Muc dich cia viéc thém cdc diéu khiển khác vào điều khiển

Trang 12

Chương 4: Đối tượng DataGridView và ADO.NET ‘abil LastName {EM Classi | Columntype - _DataGridWiewTextBoxCoki2i DataPropertyName

‘The name of the data source property or database

column to which the DataGridViewColumn is bound

Hinh 4-10: Thay déi trang thdi cét

2.1 Thém diéu khién TextBox vao DataGridView

Khi trình bày danh sách nhân viên trên diéu khién DataGridView, nếu bạn muốn định nghĩa tựa đề của cột dữ liệu thì bạn có thể thêm cột vào điều khiển DataGridView

Dé lam diéu nay, ban thém diéu khién DataGridView vào Form rồi chon và nhan R-Click | Add Column, cita sổ thêm cột xuất hiện hình 4-11 Add Column &) Databound column Columns in the DataSource Name [EmployeeID : KH Type: DataGridViewTextBoxColumn iv

Header text: |MaNhan Vien} = Se

Veible [ ] ReadOnly [] Frozen

Trang 13

(Al? 184 Chương 4: Déi tugng DataGridView va ADO.NET

Sau khi thêm 3 cot vao diéu khién DataGridView, ban chọn và R-Click | Edit Columns, cửa sổ khai báo thuộc tính cho điều khiển TextBox xuất hiện như hình 4-12 Edit Columns | (cod GEE 32767 False \nType DatzGidViewTextBoxcolu Xổi Indicates the name used in code to identify the ‘object ‘ Hình 4-12: Khơi báo thuộc tính cho điều khiển TextBox

Để khai báo cột EmployeeTD ứng với cột EmployeelD trong đối tượng DataTable, ban khai bdo trong thuéc tinh DataPropertyName nhu hinh 4-13 Edit Columns E2 a | DataGridViewTextBoxColu There of Bip cata sauce propery Seas DataGridViewColumn ‘column to which the: Hinh 4-13: Khai bdo thuéc tinh DataPropertyName

Tương tự như vậy, bạn khai báo thuộc tinh DataPropertyName cho

Trang 14

Chương 4: Déi tugng DataGridView va ADO.NET 185

í dụ 4-10: Khai báo trình bày dữ liệu

private voiđ button1_C1ick(object sender, EventArgs e)

{

// Khai bdo va khéi tao déi tugng Databases Databases cls = new Databases (); // Khai bdo vé khéi tao déi tugng DataTable

DataTable dataTable = cls.FillDataTable ( "select EmployeeID, FirstName, "+

"LastName, ClassID fromtblEmployees", CommandType Text) ; dataGridViewl DataSource = dataTable; } Khi thực thi chương trình, nếu bạn nhấn nút S»ou thì dữ liệu trình bày như hình 4-14 :

-_BNhanVien _—ˆ FisiName | LastName

.)M-00022 Dinh Tien Van | Sinh

2 : M-00028 Tat Vinh Thi Hue Thuong MAN 3M-00031 Pham Ngoc Van |Long — MAN

}M-00036 7 MAN

— M000 Dang Thuy Thi | Diem Anh MAN

}— M0042 Nguyen Quoc V |BW MAN

: M-00047 Mai Hoang Van Nam MAN M-00051 = Nguyen Ki Hình 4-14: Thém TextBox va DataGridView

Luu y, trong phat biéu SQL có 4 cột dữ liệu mà bạn chỉ thêm 3 điều

khién TextBox thi cét thứ 4 vẫn trình bày dữ liệu

2.2 Thêm điều khiển ComboBox vào DataGridView

Trang 15

Chương 4: Đối tượng DataGridView và ADO.NET

DataGridView va Button

i FirstName | LastName ý DlasslD

ADM-00022 | Dinh Tien Van Sinh Manager

ADM-00028 i Hue Thuong i

_|ADM.00081 | Pham Ngee Van 'Leng a

_|JADM-00036 |LeQuoc Van 'Hiep roca

ADM-00038 | Dang Thuy Thi Diem Anh

~ ADM-00042 | Nouyen Quoc V | Sy Manager

ADM-00047 | Mai Hoang Van Nam Manager

ADM-00051 [Nguyen Km Thị {Phuong Manager

dby /

Leader

Hình 4-15: Trinh bay danh sdch nhdn uiên

Để làm điều này, trước tiên ban thiét ké Form bao gồm điều khiển Kế đến, bạn #-Cỉck trên điều khiến

Trang 16

Chương 4: Đối tuong DataGridView va ADO.NET 187

Sau khi thém 3 diéu khién TextBox va diéu khién ComboBox vao diéu

khién DataGridView, ban cé thé R-Click | Eidt Columns và khai báo thuộc

tinh DataPropertyName nhu hinh 4-17 Edit Columns Selected Columns: Bound Column Properties feb] EmployeelD | ÂSBÏ FirstName fabl] LastName =e DataSource ˆˆ DisplayMember Í(none) Items (Collection) : ValueMember (none) ‘ClassiD i DataGridViewComboBoxCc vi

The name of the data source property or aoe phan which the DatacreVienColumns bord

Hinh 4-17: Khai bdo thuéc tinh DataPropertyName Sau đó, khai báo đoạn chương trình trong bién cé Click cia nit Show nhu vi du 4-11

í dụ 4-11: Khai báo trình bày dữ liệu

private void button1_Click(object sender, EventArgs e)

{

L1 Khai báo uà khởi tạo đối tượng Databases Databases cls = new Databases () ;

L1 Khai bdo déi tugng DataTable cho diéu khién ComboBox DataTable dataTableComboBox = cls.FillDataTable( "select * fromtblClasses", CommandType.Text) ; L1 Khai báo thuộc tính cho điều khiển ComboBox ClassID.DataSource = dataTableComboBox; ClassID.DisplayMember = "Description"; ClassID.ValueMember = "ClassID";

Trang 17

IMỊ” 1ss Chu-ng 4: Đối tượng DataGridView và ADO.NET

DataTable dataTable = cls.FillDataTable( "select EmployeeID, FirstName, "+ "LastName, ClassID from tblEmployees", CommandType Text) ;

dataGridViewl.DataSource = dataTable;

2.3 Thém diéu khién Button vao DataGridView

Dé thém diéu khién Button vao diéu khién DataGridView, ban cé thé thực hiện tương tự như hai trường hợp trên Chẳng han, bạn thiết kế Form réi chon và nhấn #-Ciick | Add Colưmn, cửa sổ thêm cột xuất hiện như hình 4-18 Add Column cảnh ales} Datsbound column Columns in the GataSource © Unbound column “Name: |Approval cae ia J Type: lãtaGridiawfiuttoriColLirnrt

Header text: : |Approval | :

/ Visible [] Read Only

add | [_cancet_]

Hình 4-18: Thém diéu khién Button vao DataGridView

Sau khi thém cét la diéu khién Button vào điều khién DataGridView,

Trang 18

Chương 4: Đối tượng DataGridView và ADO.NET Selected Column {bl] Ma Nhan Vien labl] LastName em Delete ColumnType DataGridViewButtonColumn' Indicates the name used in cade to identify the one E=IE=]

Hinh 4-19: Khai bdo thuéc tinh cho điều khiển Button

Kế đến, bạn khai bdo doan chuong trinh trong bién cd Show dé dién dữ liệu vào điều khiển Dœ/aGr¡dVieu tại thuộc tinh Text cho hai nút Aprroudl, Delete như ví dụ 4-12

í dụ 4-12: Khài báo trình bày dữ liệu

private voiđ button1_C11ick (object sender, EventArgs e)

{

// Khai bdo va khdi tao déi tugng Databases Databases cls = new Databases () ; // Khai bdo va khéi tao déi tugng DataTable

DataTable dataTable = c1s.Fi11DataTable ( "select EmployeeID, FirstName, "+ "LastName, ClassID from tblEmployees", CommandType.Text) ;

dataGridView1.DataSource = dataTable; // Duyét trén ting hang

Trang 19

190 Chương 4: Đối tượng DataGridView và ADO.NET tMa i 4 | Nhan | FirstName LastName Approval Delete Class} = Vien 1 i { i

Dinh Tien Van Sinh 0K OK _} MAN ADM-00028 | Tat Vinh Thi Hue Thuong OK OK || MAN

{ADM-00031 | Pham Ngoc Van | Long OK 0K _ | MAN ADM-00036 | Le Quoc Van Hiep 0K 0K —— |ADM-00038 |Dang Thuy Thì {DiemAnh 0K 0K _]|MAN

- JADM-00042 | Nguyen Quoc V | Sy OK 0K J|MAN

ânM.nnn47 ! Mai Hoang VAn, Nam = nk nk

Logged by ADMINISTRATOR

Hinh 4-20: Thém Button vao DataGridView

Khi người sử dụng nhấn vào một trong hai nút, bạn cần khai báo đoạn chương trình trong biến cố CelJCl¿ck để phân biệt nút bị nhấn như ví dụ 4-13 í dụ 4-13: Phân biệt nút nhấn private void đataGrigView1_ Ce11C1ick(object senđer, DataGridViewCellEventArgs e) { // Dua vao cột mà người sử dụng đang nhấn switch (e.Col1umnTndex) { case 0: MessageBox Show ("Approval for: " + Convert ToString(dataGridView1[2, e.RowIndex] Value)); break; case 1: MessageBox Show ("Delete for: "+ Convert ToString (đataGriđView1 [2, e.RowIndex] Value)); break; } }

Trang 20

Chương 4: Đối tượng DataGridView và ADO.NET 191 [MỊ?

8pproval for: ADM-00028

Hình 4-21: Nhấn nút OK trong cot Approval

Tương tự như vậy, nếu bạn nhấn vào nút OK trong cột Deiete thì kết quả trình bày như hình 4-22

a

Delete for: ADM-00036

Hình 4-22: Nhấn nút OK trong cột Delete

2.4 Thêm diéu khién CheckBox vao DataGridView

Để thêm điều khiến CheckBox vao diéu khién DataGridView, ban thiét ké Form va thém diéu khién DataGridView réi chon va nhaén R-Click

| Add Colưmn, cửa số thêm cột xuất hiện hình 4-23 ñdd Column ‘acd * 3 Databound column | ‘Columns rithe fataoource ~® Unbound column — tone: Type: DataGridviewCheckBoxColumn 5

Header text: |Avalable| m

M1 visble () Read only [TEezen

Trang 21

192 Chương 4: Đối tượng DataGridView va ADO.NET

Sau khi thêm cột kiểu CheckBox vào điều khién DataGridView, ban chọn và ?-Click | Edit Columns, cửa sổ khai báo thuộc tính cho điều khiển CheckBox xuất hiện như hình 4-24 FalseValue IndeterminateValue

Hình 4-24: Khai bdo thuéc tính cho diéu khién CheckBox

Tương tự như vậy, bạn khai báo đoạn chương trình trong biến cố

Shou như ví dụ 4-14

dụ 4-14: Khai báo trình bày dữ liệu

private void button1l_Click (object sender, EventArgs e)

{

// Khai bdo va khởi tạo đối tượng Dœtabases Databases cls = new Databases () ;

// Khai bdo va khởi tạo đối tượng DataTable

DataTable dataTable = cls FillDataTable( "select EmployeeID, FirstName, "+ "LastName, ClassID,Available from" +

"tblEmployees", CommandType.Text) ;

dataGridViewl DataSource = dataTable;

}

Khi thực thi chương trình, nếu bạn nhan nut Show thi dit liéu trinh

Trang 22

Chương 4: Đối tượng DataGridView và ADO.NET |} ADM-00028 ADM-00031 _,ADM-00036 Hes ˆ JAnM-00042 ˆ_|ADM-00047 eee | FirstName Dinh Tien Van

Tat Vinh Thi

Pham Ngoc Van LeQuoc Van Dang Thuy Thi Nguyen Quoc V Mai Hoang Van Nguyen Km Thi Sinh Hue Thuong Long Hiep Diem Anh Cae Nam Phuong ADM-00051 ADMINISTRA:

Hinh 4-25: Thém CheckBox vao DataGridView

Luu ý, nếu trong phát biểu SQL có 4 cột dữ liệu mà bạn chỉ thêm 3 điều khiển 7ex¿Box thì khi trình bày dữ liệu cột thứ 4 này vẫn xuất hiện

Ngoài ra, bạn cũng có thể trình bày thực đơn nóng mỗi khi người sử dụng nhấn nút chuột phải trên điều khiển DataGridView

Ví dụ, khi người sử dụng nhấn nút chuột phải trên điều khiển DataGridVieuo thì thực đơn xuất hiện như hình 4-26

Dinh Tien Van

ADM-00028 | Tat Vinh Thi AD! Approve Delete ADM-00042 ADM-00047 ˆ |ADM-00051 Nguyen (uoc V

Mai Hoang Van

Nguyen Kim Thi

Trang 23

194 Chương 4: Đối tượng DataGridView và ADO.NET

Để làm điều này, bạn thiết kế ContextMenuScript trên mMenu với hai menu con là Approue và Delete Sau đó, khai báo đoạn chương trình trong biến cé Click cia menu cé tén toolStripMenulItem1 tng véi Approve

nhu vi du 4-15 :

í dụ 4-15: Khai báo cho Menul

private voidđ toolSEripMenuTtem1_C1ick(object sender, EventArgs e) { MessageBox Show("EmployeeID is " + Convert ToString ( dGataGridViewl.CurrentCell.Value) ); }

2.5 Dinh dang cho 6

Để định dạng ô trong điều khiển DataGridView, ban c6 thé chon vào thuộc tính DeƒfbuitCellStyle, cửa sổ xuất hiện như hình 4-27

[82)013/0287/10/00 210

previews att Bee: a5 là

Trang 24

Chương 4: Đối tuong DataGridView va ADO.NET 195

Khi thực thi chương trình, nếu bạn nhấn nút S»ou thì dữ liệu trình bày với cột thứ nhất xuất hiện màu như hình 4-28

DataGridView - [frmCetlStyte]

Ma Nhan Vien + FirstName | LastName: ? ClassID

Dinh Tien Van Sinh MAN

Tat Vinh Thi Hue Thuong MAN Pham Ngoc Van {Long MAN Le Quoc Van Hiep MAN

Dang Thuy Thi | Diem Anh MAN

Nguyen Quoc V | Sy MAN Mai Hoang Van Nam MAN Nguyen Kim Thì {Phuong - oy MAN mtg

| Loosed by AptamvisTRATOR

Hinh 4-28: Khai bdo mau cho cét

Trong trường hợp bạn muốn định dạng cho những ô còn lại của điều khién DataGridView, ban cé thé khai báo đoạn chương trình sử dụng đối tuong DataGridViewCellStyle va thudc tinh DefaultCellStyle trong biến cố Click cia nit Apply Style nhu vi du 4-16

i du 4-16: Khai bao dinh dang cho 6

private void button2_Click(object sender, EventArgs e) { DataGridViewCellStyle CellStyle = new DataGridViewCellStyle()j; CellStyle.BackColor = Color.Bisque; CellStyle.ForeColor = Color.Blue; dataGridViewl DefaultCellStyle = CellStyle;

Trang 25

IMỊ” 196 Chương 4: Đối tượng DataGridView và ADO.NET

Hinh 4-29: Dinh dang mau

3 ĐỐI TƯỢNG BINDINGSOURCE

Thay vì bạn phải khai báo để liệt kê danh sách mẩu tin của bảng con khi người sử dụng di chuyển trên từng mẩu tin của bảng cha thì bạn có thể sử dụng đối tượng BindingSource cùng với đối tượng DœfaSet và DataRelation

Chẳng hạn, bạn muốn liệt kê danh sách phòng ban trên điều khiển DataGridVieu, mỗi khi người sử dụng chọn vào mã phòng ban thì danh sách nhân viên và hợp đồng lao động của họ sẽ liệt kê trên điều khiển

DataGridView thứ hai như hình 4-30

Dinh Tien Van Sinh C000000161 'ADM-00022 !4/28/200

Tat Vinh Thi Hue Thuong | (000000162 -ADM.00028 | 5/28/200

Trang 26

Chương 4: Đối tượng DataGridView và ADO.NET 197 Để làm điều này, trước tiên bạn thiết kế Form bao gồm hai diéu

khién DataGridView va Button nhu hinh 4-31

Hình 4-31: Thiét ké Form dung doi tuong BindingSource

Ké dén, ban khai bdo phuong thtte MakeBindingSource nhan hai

tham số là BindingSource ứng với bảng cha là £b1Departmen‡s và con là sự

kết hợp giữa hai bảng tblEmployees va tblContracts nhu vi du 4-17

í dụ 4-17: Khai báo sử dụng đối tượng BindingSource

Void MakeBindingSource (

BindingSource bindingParent,

BindingSource bindingChild)

{

// Khai bdo va khởi tạo đối tượng Dœtabases Databases c1s = new Databases () ;

!1 Khai báo phát biểu SQL ting voi bang cha

string parentSQL = "select DeptID, "+ "DeptName from tblDepartments";

!1 Khai báo phát biểu SQL ứng uới hai bảng con string childSQL= "select FirstName, "+

"Lastname,* from tbhlContracts C, "+ "tblEmployees E where E.EmployeeID=" + "C.EmployeeID";

// Khai báo đối tượng DataSet

DataSet dataSet =cls.FillDataSet (

Trang 27

Chương 4: Đối tượng DataGridView và ADO.NET L1 Khai báo đối tượng DataColưmnn ứng uới L1 cột khóa chính DataColumn pk = dataSet.Tables[0].Columns[0]; // Khai báo đối tượng DataColumn ứng uới bhóa ngoại DataColumn £k = dataSet.Tables[1i].Columns[15]; // Khai bdo va khdi tao d6i tuong DataRelation DataRelation dr = new DataRelation("Relation", pk, £k, true);

// Khai báo thém déi tuong DataRelation vao /1 đối tượng DataSet

dataSet.Relations.Add(dr);

// Khai bdo thuéc tinh DataSource cho

LJ đối tượng BindingSource

bindingParent DataSource = dataSet; bindingParent DataMember = "tblDepartments"; bindingChild.DataSource = bindingParent; bindingChild.DataMember = "Relation"; } Sau đó, bạn gọi phương thức này trong bién cé Click cia nit Show nhu vi du 4-18

i du 4-18: Khai bao goi phuong thức MakeBindingSource

private void button1l_Click (object sender, EventArgs e) { try { // Khai bdo va khdi tao déi tượng BindingSource // tng uới bảng chư BinđingSource binđingParent = new BindingSource();

// Khai bdo va khdi tao déi tuong BindingSource

// ứng uới bảng hai bang con

BindingSource bindingChild =

Trang 28

Chương 4: Đối tượng DataGridView và ADO.NET

11 Khai báo gọi phương thức MuheBindingSource MakeBindingSource ( bindingParent, bindingChild) ; L1 Khai báo thuộc tính cho hai điều khiển DataGridView đataGriđView1.DataSource = bindingParent; dataGridView2.DataSource = bindingChild; } catch (Exception ex) { MessageBox Show(ex.Message) ; } }

Mỗi khi người sử dụng chọn mẩu tin trên điều khiển Dœ/gGridVieio thứ nhất thì danh sách mẩu tin có mã phòng ban trong bảng tblContracts

tương ứng sẽ trình bày tương tự như hình 4-32 Z] DataGridView - [frmBindingSource] | ContrectNo j EmployeslD ˆ C000121250 DTY-00014 Ton That Van 900000012 DTY-00014

LaVan Tủ Van, £nnnmnin1 n1v.an18 Hình 4-39: Lọc đữ liệu

4 DOL TUGNG BINDINGNAVIGATOR

Nếu như bạn muốn cho phép người sử dụng di chuyển trên từng mẩu tin của bảng cha mà khong truc tiép chon trén diéu khién DataGridView thi bạn có thể sử dụng ddi tugng BindingSource kết hợp với

BindingNavigator

Trang 29

Chương 4: Đối tượng DataGridView và ADO.NET Logged by ADMINISTRATOR —— — : Š 2

Hinh 4-33: Siz dung BindingNavigator

Kế đến, bạn khai báo phương thức có tên MakeBindingSource nhận

hai tham số là BindingSource ứng với bảng cha là tblDepartments va con la

sự kết hợp giữa hai bảng £b1Employees và tblContracts như ví dụ 4-19 Vi du 4-19: Kh ai báo sử dụng đối tượng BindingSouree void MakeBindingSource( BindingSource bindingParent, BindingSource bindingChild) {

11 Khai báo va khối tạo đối tượng Databases

Databases c1s = new Databases () ; // Khai báo phát biểu SQL ứng uới bảng cha string parentSQL = "select *"+

" from tblDepartments";

11 Khai báo phát biểu SQL ứng uới hơi bảng con

string childSQL = "select FirstName, "+ "Lastname, * from tblContracts C, "+

"tblEmployees E where E.EmployeeID=" + "C.EmployeeID";

// Khai bdo déi tugng DataSet

DataSet dataSet =cls.FillDataSet (

parentSQL, "tblDepartments", childSQL, "tblContracts", CommandType Text) ; 11 Khai báo đối tượng DataColumn ứng uới

Trang 30

Chương 4: Đối tượng DataGridView và ADO.NET 201 DataColumn pk = dataSet.Tables[0].Columns[0]; // Khai bdo déi tugng DataColumn ting vdi khéa ngoại DataColumn fk =

dataSet Tables[1] Columns[15]; L1 Khai báo uà bhởi tạo đối tượng DataRelation DataRelation dr = new

DataRelation("Relation", pk, fk, true); LỊ Khai báo thêm đối tượng DataRtelation uào

/[I đối tượng DataSet

đataSet Relations Add (đr) ;

L] Khai báo thuộc tính DataSource cho

L1 đối tượng BindingSource bindingParent.DataSource = dataSet; bindingParent DataMember = "tblDepartments"; bindingChild DataSource = bindingParent; bindingChild.DataMember = "Relation"; }

Sau đó, bạn khai báo để gọi phương thức này trong biến cố Cỉ¡ck của nut Show nhu vi dụ 4-20

i du 4-20: Khai báo gọi phương thức MakeBindingSource

private void button1_C1ick(ob3ject senđer, EventArgs e) { try { L1 Khai báo uò khởi tạo đối tượng BindingSource L1 ứng uới bảng chư BindingSource bindingParent = new BindingSource() ;

// Khai bdo va khdi tao dbi tugng BindingSource

L1 ứng uới bảng hai bảng con

BindingSource bindingChild = new BindingSource() ;

Trang 31

Chương 4: Đối tugng DataGridView va ADO.NET

bindingParent, bindingChild) ;

L1 Khai báo uà khởi tạo đối tượng BindingNauigator // ứng uới bảng hai bang con BindingNavigator bindingNavigator; bindingNavigator = new BindingNavigator (true) ; bindingNavigator.Parent = this; bindingNavigator.BindingSource = bindingParent;

// Khai bdo thuéc tinh cho hai diéu khién DataGridView dataGridViewl DataSource = bindingParent;

dataGridView2 DataSource = bindingChild; } catch (Exception ex) { MessageBox Show(ex.Message) ; } }

Khi thực thi chương trình, nếu bạn nhấn nút S»ou thì dữ liệu của ba bảng được trình bày như hình 4-34 {| DeptDisPayrols DeptDisSocial | 'DeptDisHeath #4[ — 141.45 789 142 45.780 142 45.770 2 14145790 |14245781 |14245771 145731 /14245782 1142.45.72 ee 1b {Contacte 7 Employes fcT €000000161 ADM-00022 4h CO00000182 |ADM-00028 5; £nnnnnni5s anM.fnn31 z3)

Hình 4-34: Sở dụng đối tượng BindingNquigdtor

Lưu ý, bạn có thể chọn nút › hay 4 để di chuyển trên từng mẩu tin của

bảng tblDepartments

Trang 32

Chương 4: Đối tượng DataGridView và ADO.NET “Tle Quoc Van ÌHep cooo000040 — ;ADM-00036

Hình 4-85: Sử dụng đối tượng BindingNauigdtor

Để làm điều này, trước tiên bạn thiết kế Form có giao diện như hình 4-36 Logged by ADMINISTRATOR

Hinh 4-36: Đối tượng BindingNavigator va TextBox

Kế đến, ban khai bdo phuong thuc c6 tén GetDataSet nhan hai tham sé 1a BindingSource tmg véi bang cha 1a tblDepartments va con 1a su kết hợp hai bang tblEmployees va tblContracts tra về đối tugng DataSet như ví dụ 4-21

{ du 4-21: Khai báo sử dụng đối tượng BindingSource DataSet GetDataSet (

BindingSource bindingParent, BindingSource bindingChild)

Trang 33

Bal? 204 Chương 4: Đối tượng DataGridView và ADO.NET

}

// Khai báo uà khởi tạo đối tượng Databases Databases cls = new Databases();

LJ Khai báo phát biểu SQL ứng uới bảng chư string parentSQL = "select *"+

" from tblDepartments";

// Khai báo phát biểu SQL ứng uới hai bang con string childSQL = "select FirstName, "+

"Lastname,* from tblContracts C, "

"tblEmployees E where E.EmployeeID=" +

"C.EmployeeID"; // Khai bdo doi tuong DataSet

DataSet dataSet = cls.FillDataSet (

parentSQL, "tblDepartments", childSQL, "tblcontracts", CommandType Text) ; /1 Khai bdo déi tugng DataColumn ting voi

/1 cột hhóa chính

DataColumn pk =

dataSet.Tables[0].Columns[0];

/1 Khai bdo déi tượng DataColumn ứng uới khóa ngoại

DataColumn £k = đataSet.Tables[1] Columns[15]; 11 Khai báo uè khởi tạo đối tượng DataRelation

DataRelation dr = new

DataRelation("Relation" pk, £k, true);

// Khai báo thêm đối tượng DataRelation uào /1 đối tượng DataSet

đataSer Relatrions Ađđ (đr) ; L1 Khai báo thuộc tính DataSource cho /1 đối tượng BindingSource

Trang 34

Chuong 4: Déi tugng DataGridView va ADO.NET 205 MỊ?

í dụ 4-22: Khai báo gọi phương thức GetDataSet

private voiđ button1_C1ick(object sender, EvenEArgs e) { try { LỊ Khai báo 0à khởi tạo đối tượng BindingSource L1 ứng uới bảng chư BindingSource bindingParent = new BindingSource() ;

11 Khai báo uò khởi tạo đối tượng BindingSource // ting voi bảng hai bảng con

BindingSource bindingChild =

new BindingSource() ;

LỊ Khai báo gọi phương thức GetDataSet

DataSet dataSet = GetDataSet (

bindingParent, bindingChild) ;

|| Khai bdo va khéi tao déi tueong BindingNavigator // tng voi bang hai bảng con BindingNavigator bindingNavigator; bindingNavigator = new BindingNavigator (true) ; bindingNavigator Parent = this; bindingNavigator.BindingSource = bindingParent;

// Khai bdo thuéc tinh cho hai điều khiển TextBox

Trang 35

Chương 4: Đối tượng DataGridView và ADO.NET Name [Engineering d |

\'FustName Lawnameˆˆˆ ConuaclNoˆ ' EmployeelD

biện Due C000000530 ENG-00193

TianVanVan | Tam C000001180 ENG-90001 lạ,

S {Tran Van Van ¡Tam C000000320 ENG-90001 - J4

PhanKhac Van |Hien C000000017 ENG-90003 4/3 3t = Logged by ADMINISTRATOR, _ Vlveteontseeah: Fin a lea Ni Raat A Fit 23 3

Hình 4-37: Sử dụng đối tượng BindingNavigator

Trang 36

Chương 4: Đối tượng DataGridView và ADO.NET 5 KHAI BÁO PHƯƠNG THỨC SỬ DỤNG CHUNG

Sau khi khai báo và sử dụng đối tượng Dœ¿aGridVi¡eu và các đối tượng

như: Dœ¿aSet, DœtœTable, DataVieu, chúng ta có thể khai báo hai phương

thức dùng chung cho điều khiển nay véi hai déi tugng DataTable, DataView trong lớp Controls

Phương thức thứ nhất nhận tham số là phat biéu SQL, diéu khién ° DataGridView va loai câu truy vấn như ví dụ 4-23

í dụ 4-28: Khai báo phương thức dùng chung

internal void FillControls (

DataGridView dataGridView, string strSQL, CommandType commandType) { try { DataTable dataTable = cls.FillDataTable(strSQL, commandType) ; dataGridView DataSource = dataTable; } catch (Exception ex) MessageBox Show(ex.Message ) ; } }

Tương tự như vậy, trong trường hợp bạn cho phép người sử dụng trích

lọc dữ liệu thì khai báo phương thức có thêm tham số là đối tượng DataTable và chuỗi ứng với thuộc tính RouFiiter của đối tượng DœœVieu như ví dụ 4-24

Trang 37

Chương 4: Đối tượng DataGridView và ADO.NET

dataGridView DataSource = đataView; ae (Exception ex) : MessageBox Show(ex.Message) ; ' } Để sử dụng hai phương thức này, trước tiên bạn thiết kế Form có giao diện như hình 4-39 EIEIE] (bass [bay], Hình 4-89: Sở dụng phương thúc dùng chung

Kế đến, khai báo đoạn chương trình trong biến cố Ciiek của nút DataTable dé goi phuong thi FillControls tht nhat nhu vi du 4-25

í dụ 4-25: Khai báo gọi phương thức dùng chung

brivate void button2_C1ick(object senđer, EventArgs e)

{

// Khai bdo va khởi tạo đối tượng Controls Controls cls = newControls();

// Khai báo gọi phương thức FillControls

c€l1s.Fi11Controls (this đataGridView1,

Trang 38

Chuong 4: Déi tugng DataGridView va ADO.NET 209 MỊ”

Khi thực thi chương trình, nếu bạn nhấn vào nut DataTable thi két quả trình bày danh sách hợp đồng của nhân viên như hình 4-40 ES] DataGridView - [frmUse]

Contacto | EmployeelD | ContractDate | ContiactTyr| Commencement |^

‘\cooooo0002 |ENG-90032 | 4/28/2006 One Year | 4/28/2006 6:53 |C000000012 |DTY-00014 | 4/28/2006 6:59 |No Limit | 4/28/2006 6:59 — fco00000013 |DTY-00020 | 4/28/2006 6:59 |NoLimit | 4/28/2006 6:59

Co00000014 |ADM-80095 | 4/28/2006 6:59 |One'Year | 4/28/2006 6:59

_ }cooo000g1s |ADM-80096 | 4/28/20066:59 |NoLimit | 4/28/2006 6:59 _ [cooo000016 |ADM-80088 |4/28/2006653 One Year | 4/28/2006 6:53 [Ẵ000000017 |ENG-90003 |4/28/20066/59 OneYear | 4/28/2006 6:53 ~ }co00000018 |ENG-90004 | 4/28/2006 6:59 4/28/2006 6:59 aaa Hình 4-40: Danh sách hợp đồng lao động

Tương tư như vậy, nếu bạn có nhu cầu truy trích lọc dữ liệu trên đối

tugng DataTable thi bạn có thể trích lọc dữ liệu trong déi tugng DataTable bằng cách khai báo tương tự như ví dụ 4-26

Ví dụ 4-26: Khai báo gọi phương thức dùng chung

private void button3_Click(object sender, EventArgs e)

{

LỊ Khai báo uà khởi tạo đối tượng Databases Databases đatabase = new Databases () ;

Trang 39

° 210 Chương 4: Đối tung DataGridView va ADO.NET

Nếu bạn nhấn vào nut DataView thi két qua trinh bay danh sách hợp đông của nhân viên như hình 4-41 £ DataGridView - [frmUse] D | ContractDate "| ContractT yp % 4/28/2008 6:59 | One Year 4/28/2008 = 4/28/2006 6:58 | No Limit 4/28/2008 4/28/2006 6.53 | One Year 4/28/2008 5/28/2006 7.01 | One Year 5/28/2006 5/28/2006 7:01 |One Year 5/28/2006 ADM-80121 4/28/2006 6:53 | One Year 4/28/2006 ADM-60134 4/28/2006 6:59 | One Year 4728/2006 ADM-80100 4/28/2006 6:59 | One Year 4/28/2008 v2 š Hình 4-41: Lọc mẩu tin 6 KẾT LUẬN

Chúng ta vừa tìm hiểu cách khai báo và sử dụng đối tượng DataGridView véi cdc déi tugng nhu: DataSet, DataTable, DataView,

BindingSource va BindingNavigator

Trong chương kế tiếp, chúng ta tiếp tục tìm hiểu cách sử dụng Repor¿,

Crystal Report với hai điều khiển ReportVieuer và CrystalReportVieuer

Trang 40

Chuong 5: Lam viéc véi Report va Crystal Report 211 [MỊ? Chương 5ð: LÀM VIỆC VỚI REPORT VÀ CRYSTAL REPORT Tóm tắt chương õ

Bạn uừa tìm hiểu cách khơi báo uà sử dụng thành phan chính của biến trúc không kết nối ADO.NET là đối tượng DœtaSet va DataTable, cdch trình bày dữ liệu trên điều khiển DataGridView uò điều hướng uào một số điều khiển khác

Trong chương này, chúng ta sẽ tiếp tục tìm hiểu cách trình bày dữ liéu trén Report, Crystal Report bang diéu khién

ReportViewer, CrystalReportViewer từ đối tuong DataSet,

DataTable, DataView hay OLEDB (ADO) Các uấn đề chính sẽ được đề cập:

v_ Thiết ké Crystal Report

Y Trinh bay dit liéu bang CrystalReportViewer Y Trinh bay dit liu bang Report va ReportViewer

Phương thức dùng chung

1 THIẾT KẾ CRYSTAL REPORT

Để làm việc véi Crystal Report, ban cé thé tạo mới Projec£ loại Crystal Reports Application hoac tu khai báo tham chiéu dén khéng gian

tên trong du dn loai Windows Forms

Mặc dù Microsoft đã thiết kế, tạo kết nối và tương tác bằng nhiều

cách khác nhau cho Crystal Report, nhung trong chuong nay chúng tôi sẽ

giới thiệu đến các bạn cách sử dụng đối tugng DataSet, DataTable va

OLEDB (ADO)

Có hai cách để thực hiện ý định này Cách thứ nhất là thêm đối tượng

DataSet tit ngan Data trong cita s6 ToolBox vao Form Cach thu hai, khai bdo bién déi tugng DataSet trong Class tury y Ca hai cach nay cho phép ban

Ngày đăng: 17/12/2021, 10:02

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w