Tài liệu Đề cương Lập trình Winform và ADO.NET: 1 
TRƢỜNG ĐẠI HỌC SƢ PHẠM KỸ THUẬT HƢNG YÊN 
KHOA CÔNG NGHỆ THÔNG TIN 
ĐỀ CƢƠNG 
HỌC PHẦN: LẬP TRÌNH WINFORM VÀ ADO.NET 
Hƣng Yên 
(Tài liệu lƣu hành nội bộ) 
2 
MỤC LỤC 
BÀI 1: TỔNG QUAN .......................................................................................................................... 4 
1.1. Giới thiệu về Net Framework ............................................................. 4 
1.2. Giới thiệu về Windows Form.............................................................. 5 
BÀI 2: MỘT SỐ ĐIỀU KHIỂN WINFORM (1) ................................................................... 15 
2.1. Label ( ) ................................................................................ 15 
2.2. TextBox( ) ........................................................................ 16 
2.3. Button ( ) .................................................................. 17 
2.4. CheckBox ( ) ........................................................ 18 
2.7. R...
                
              
                                            
                                
            
 
            
                 113 trang
113 trang | 
Chia sẻ: putihuynh11 | Lượt xem: 1518 | Lượt tải: 2 
              
            Bạn đang xem trước 20 trang mẫu tài liệu Đề cương Lập trình Winform và ADO.NET, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
1 
TRƢỜNG ĐẠI HỌC SƢ PHẠM KỸ THUẬT HƢNG YÊN 
KHOA CÔNG NGHỆ THÔNG TIN 
ĐỀ CƢƠNG 
HỌC PHẦN: LẬP TRÌNH WINFORM VÀ ADO.NET 
Hƣng Yên 
(Tài liệu lƣu hành nội bộ) 
2 
MỤC LỤC 
BÀI 1: TỔNG QUAN .......................................................................................................................... 4 
1.1. Giới thiệu về Net Framework ............................................................. 4 
1.2. Giới thiệu về Windows Form.............................................................. 5 
BÀI 2: MỘT SỐ ĐIỀU KHIỂN WINFORM (1) ................................................................... 15 
2.1. Label ( ) ................................................................................ 15 
2.2. TextBox( ) ........................................................................ 16 
2.3. Button ( ) .................................................................. 17 
2.4. CheckBox ( ) ........................................................ 18 
2.7. RadioButton ( ) ......................................................... 26 
BÀI 3. THỰC HÀNH 1 – CÁC ĐIỀU KHIỂN WINFORM (1) .................. 28 
BÀI 4. MỘT SỐ ĐIỀU KHIỂN WINFORM (2) ................................................................... 28 
4.1. Timer ( ) .............................................................................. 28 
4.2. RichTextBox ( ) ........................................................... 29 
4.3. PictureBox ( ) ............................................................. 30 
4.4. ImageList ( ) ............................................................... 30 
4.5. Image ( ) ..................................................................... 30 
4.6. Điều khiển ListView ( ) ................................................ 31 
4.7. Treeview ( ) .................................................................... 45 
4.8. DataGridView ................................................................................... 47 
BÀI 5: THỰC HÀNH 2 – CÁC ĐIỀU KHIỂN WINFORM (2) .................................... 52 
BÀI 6: MỘT SỐ ĐIỀU KHIỂN WINFORM (3) ................................................................... 52 
6.1. MenuStrip ............................................................................................... 52 
6.2. Các điều khiển hộp thoại ....................................................................... 55 
BÀI 7. THỰC HÀNH 3 – CÁC ĐIỀU KHIỂN WINFORM (3) .................................... 60 
BÀI 8. GIỚI THIỆU VỀ ADO.NET ........................................................................................... 60 
8.1. Giới thiệu về ADO.NET ................................................................... 60 
8.2. Các mô hình thao tác với CSDL ....................................................... 61 
8.3. Đối tƣợng Connection ....................................................................... 62 
BÀI 9. THỰC HÀNH 4- KẾT NỐI CSDL VỚI ĐỐI TƢỢNG CONNECTION ... 64 
BÀI 10: ĐỐI TƢỢNG COMMAND, DATAREADER, PARAMETER ................... 64 
10.1. Đối tƣợng Command......................................................................... 64 
10.2. Đối tƣợng DataReader ...................................................................... 65 
10.3. Đối tƣợng Parameter ......................................................................... 66 
10.4. Các thao tác thêm, sửa, xóa dữ liệu theo mô hình hƣớng kết nối. .... 68 
BÀI 11. THỰC HÀNH 5 – THAO TÁC CSDL THEO MÔ HÌNH HƢỚNG KẾT NỐI . 75 
3 
BÀI 12. ĐỐI TƢỢNG DATA ADAPER VÀ DATASET ................................................ 75 
12.1. Đối tƣợng DataAdaper ...................................................................... 75 
12.2. Đối tƣợng DataSet............................................................................. 75 
12.3. Nạp dữ liệu vào DataSet ................................................................... 79 
12.4. Cập nhật CSDL bằng DataAdapter ................................................... 81 
12.5. Các thao tác với CSDL theo mô hình phi kết ................................... 82 
BÀI 13: THỰC HÀNH 6 – THAO TÁC CSDL THEO MÔ HÌNH PHI KẾT NỐI88 
BÀI 14. SẮP XẾP VÀ TÌM KIẾM DỮ LIỆU VỚI DATAVIEW ................................ 88 
14.1. Đối tƣợng DataView ......................................................................... 88 
14.2. Tìm kiếm, sắp xếp, trích lọc thông tin với DataView ....................... 89 
BÀI 15. THỰC HÀNH 7 – THỰC HIỆN THAO TÁC VỚI CƠ SỞ DỮ LIỆU SỬ DỤNG DATAVIEW .. 92 
BÀI 16. LẬP BÁO CÁO VỚI CYSTALREPORT .............................................................. 92 
16.1. Giới thiệu .............................................................................................. 92 
16.2. Thiết kế một báo cáo sử dụng Report Design Environment ............. 92 
16.3. Preview báo cáo .............................................................................. 108 
16.4. Nạp và hiển thị Report trong chƣơng trình ..................................... 109 
4 
BÀI 1: TỔNG QUAN 
1.1. Giới thiệu về Net Framework 
Microsoft .NET gồm 2 phần chính : Framework và Integrated Development Environment (IDE). 
Framework cung cấp những gì cần thiết và căn bản, chữ Framework có nghĩa là khung hay khung cảnh 
trong đó ta dùng những hạ tầng cơ sở theo một qui ƣớc nhất định để công việc đƣợc trôi chảy. IDE 
thì cung cấp một môi trƣờng giúp chúng ta triển khai dễ dàng, và nhanh chóng các ứng dụng dựa trên 
nền tảng .NET. Nếu không có IDE chúng ta cũng có thể dùng một trình soạn thảo ví nhƣ Notepad hay 
bất cứ trình soạn thảo văn bản nào và sử dụng command line để biên dịch và thực thi, tuy nhiên việc 
này mất nhiều thời gian. Tốt nhất là chúng ta dùng IDE phát triển các ứng dụng, và cũng là cách dễ sử 
dụng nhất. 
Thành phần Framework là quan trọng nhất .NET là cốt lõi và tinh hoa của môi trƣờng, còn 
IDE chỉ là công cụ để phát triển dựa trên nền tảng đó thôi. Trong .NET toàn bộ các ngôn ngữ C#, Visual 
C++ hay Visual Basic.NET đều dùng cùng một IDE. 
Tóm lại Microsoft .NET là nền tảng cho việc xây dựng và thực thi các ứng dụng phân tán thế hệ 
kế tiếp. Bao gồm các ứng dụng từ client đến server và các dịch vụ khác. Một số tính năng của 
Microsoft .NET cho phép những nhà phát triển sử dụng nhƣ sau: 
- Một mô hình lập trình cho phép nhà phát triển xây dựng các ứng dụng dịch vụ web và ứng 
dụng client với Extensible Markup Language (XML). 
- Tập hợp dịch vụ XML Web, nhƣ Microsoft .NET My Services cho phép nhà phát triển đơn 
giản và tích hợp ngƣời dùng kinh nghiệm. 
- Cung cấp các server phục vụ bao gồm: Windows 2000, SQL Server, và BizTalk Server, 
tất cả điều tích hợp, hoạt động, và quản lý các dịch vụ XML Web và các ứng dụng. 
- Các phần mềm client nhƣ Windows XP và Windows CE giúp ngƣời phát triển phân phối sâu 
và thuyết phục ngƣời dùng kinh nghiệm thông qua các dòng thiết bị. 
- Nhiều công cụ hỗ trợ nhƣ Visual Studio .NET, để phát triển các dịch vụ Web XML, ứng 
dụng trên nền Windows hay nền web một cách dể dàng và hiệu quả. 
Kiến trúc .NET Framework 
.NET Framework là một platform mới làm đơn giản việc phát triển ứng dụng trong môi trƣờng 
phân tán của Internet. .NET Framework đƣợc thiết kế đầy đủ để đáp ứng theo quan điểm sau: 
- Để cung cấp một môi trƣờng lập trình hƣớng đối tƣợng vững chắc, trong đó mã nguồn 
đối tƣợng đƣợc lƣu trữ và thực thi một cách cục bộ. Thực thi cục bộ nhƣng đƣợc phân tán 
trên Internet, hoặc thực thi từ xa. 
- Để cung cấp một môi trƣờng thực thi mã nguồn mà tối thiểu đƣợc việc đóng gói phần mềm và 
sự tranh chấp về phiên bản. 
5 
- Để cung cấp một môi trƣờng thực thi mã nguồn mà đảm bảo việc thực thi an toàn mã nguồn, 
bao gồm cả việc mã nguồn đƣợc tạo bởi hãng thứ ba hay bất cứ hãng nào mà tuân thủ theo 
kiến trúc .NET. 
- Để cung cấp một môi trƣờng thực thi mã nguồn mà loại bỏ đƣợc những lỗi thực hiện các 
script hay môi trƣờng thông dịch. 
- Để làm cho những ngƣời phát triển có kinh nghiệm vững chắc có thể nắm vững nhiều kiểu ứng 
dụng khác nhau. Nhƣ là từ những ứng dụng trên nền Windows đến những ứng dụng dựa trên 
web. 
- Để xây dựng tất cả các thông tin dựa triên tiêu chuẩn công nghiệp để đảm bảo rằng mã 
nguồn trên .NET có thể tích hợp với bất cứ mã nguồn khác. 
Các thành phần của .NET FrameWork 
.NET Framework có hai thành phần chính: Common Language Runtime (CLR) và thƣ viện 
lớp .NET Framework. CLR là nền tảng của .NET Framework. Chúng ta có thể hiểu runtime nhƣ là 
một agent quản lý mã nguồn khi nó đƣợc thực thi, cung cấp các dịch vụ cốt lõi nhƣ: quản lý bộ nhớ, 
quản lý tiểu trình, và quản lý từ xa. Ngoài ra nó còn thúc đẩy việc sử dụng kiểu an toàn và các hình 
thức khác của việc chính xác mã nguồn, đảm bảo cho việc thực hiện đƣợc bảo mật và mạnh mẽ. 
Thƣ viện lớp, một thành phần chính khác của .NET Framework là một tập hợp hƣớng đối tƣợng 
của các kiểu dữ liệu đƣợc dùng lại, nó cho phép chúng ta có thể phát triển những ứng dụng từ những 
ứng dụng truyền thống command-line hay những ứng dụng có giao diện đồ họa (GUI) đến những ứng 
dụng mới nhất đƣợc cung cấp bởi ASP.NET, nhƣ là Web Form và dịch vụ XML Web. 
1.2. Giới thiệu về Windows Form 
Windows Form là ứng dụng có giao diện đồ họa chạy trên hệ điều hành Window (GUI - 
Graphical User Interface), Windows Forms là ứng dụng chạy trên máy tính của ngƣời dùng (DeskTop). 
6 
Khác với Web Forms là ứng dụng chạy trên Web Forms. Khi ứng dụng chạy thì hiển thị kết quả lên trình 
duyệt. Windows Forms là một phần của kiến trúc .NET 
Ví dụ nhƣ: 
GUI đƣợc thiết kế bằng việc thêm vào Form những điều khiển phù hợp cho yêu cầu của mỗi bài 
toán đặt ra. 
1.2.1. Các thao tác với Project / Solution 
a. Tạo Project 
C1. Vào menu File | New | Project 
C2. Ctrl + Shift + N 
 C3. Chọn công cụ New Project trên thanh Standart 
Bƣớc 1: Khởi động VS2008 và chọn Fille  New Project  
Bƣớc 2: Chọn Ứng dụng dạng Windows Forms Application, chọn nơi lữu trữ Project (xem hình)  
nhấn OK. 
7 
1.2.2. Thêm và điều chỉnh các điều khiển 
Sau khi tạo dự án, một Form đƣợc tạo ra nhƣ hình bên dƣới: 
 Để thêm các điều khiển vào Form, chúng ta có thể kéo các điều khiển bên công cụ 
Toolbox vào Form đó. 
8 
 Để chỉnh sửa các điều khiển (thêm, thay đổi kích thƣớc, xóa) chúng ta có thể chọn các điều 
khiển nhấn nút Delete nếu muốn xóa, nếu muốn thay đổi kích thƣớc thì chúng ta chỉ việc chọn vào 
điều khiển và kéo điều khiển có kích thƣớc nhƣ mong muốn: 
1.2.3. Tải các tập tin 
Visual Studio hỗ trợ làm việc với nhiều tập tin (xml, Excel, Word) với những tập tin đơn giản 
chúng ta có thể chỉnh sửa trực tiếp trên bộ công cụ này. Các file này hiển thị trên công vụ Solution 
Explorer: 
9 
Để chỉnh sửa nội dung file chúng ta có thể click trực tiếp vào file và sửa trên hộp thoại hiện ra: 
1.2.4. Thay đổi kích thước các Form 
Form (hay còn gọi điều khiển Form) dùng để chứa các điều khiển khác (Buttons, Label) 
Trong một dự án có thể có nhiều Form: 
10 
Tùy theo mỗi ứng dụng khác nhau mà chúng ta có các yêu cầu về kích thƣớc Form khác nhau cho 
phù hợp với chƣơng trình. Để thay đổi kích thƣớc Form chúng ta chỉ cần chọn Form kéo một trong các ô 
vuông hiện ra ở bên mép của Form: 
Hoặc chúng ta có thể thay đổi trực tiếp kích thƣớc của Form thông qua thuộc tính Size: 
b. Mở Project / Solution: 
C1. Vào menu File | Open | Project / Solution C2. 
Ctrl + Shift + O 
c. Lưu Project / Solution 
C1. Vào menu File | Save All 
C2. Chọn công cụ Save All trên thanh Standart 
d. Đóng Solution: Vào menu File | Close Solution 
1.2.5. Màn hình giao diện của Windows Forms 
a. Cửa sổ thiết kế Form (Designer): 
11 
b. Cửa sổ thiết viết code: 
1.2.6. Các thao tác với Form 
a. Thêm một Form mới vào Project: 
b1. C1. Vào menu Project | Add New Item  
C2. Chọn công cụ Add New Item trên thanh Standart b2. 
Khai báo 
+ Categories: chọn Windows Forms 
+ Templates: chọn Windows Form 
+ Name: đặt tên Form b3. 
Nhắp Add 
b. Thêm một Form có sẵn vào Project: b1. 
Vào menu Project | Add Existing Item  b2. 
Chọn Form 
b3. Nhắp Add 
c. Xóa bỏ một Form đang có trong Project: 
b1. Chọn Form cần gỡ bỏ (ở cửa sổ Solution Explorer) 
b2. Vào menu Edit | Delete 
12 
d. Lưu Form 
Vào menu File | Save Form.cs 
Ctrl + S 
 Ghi chú 
- Ta kéo vào form các đối tƣợng nhƣ: Label, TextBox, Button,  
+ Label, TextBox, Button,  đƣợc gọi là control hay còn gọi là component. 
+ Form đƣợc gọi là control “chứa”. 
- Khi thay đổi nội dung của Label, TextBox, Button,  ta thay đổi vào Text. Text đƣợc 
gọi là Property của control. 
1.2.7. Control là gì? 
Control là lớp (class) các thành phần đƣợc thêm vào Windows Forms để tƣơng tác giữa ngƣời 
sử dụng với Windows. 
Có rất nhiều loại control trong Windows Forms nhƣ: Label, TextBox, ListBox, 
ComboBox, Button,  
Các control sử dụng trên Windows Forms dùng namespace System.Windows.Forms. 
a. Properties (thuộc tính) của control 
Properties là những thông tin mà ta có thể thay đổi nội dung, cách trình bày của ngƣời thiết 
kế để ứng dụng vào control. 
Mỗi lớp (class) có nhiều property khác nhau. Tuy nhiên, vẫn có một số property giống nhau 
đƣợc xây dựng từ lớp ban đầu. 
Bảng trình bày các thuộc tính (Properties) giống nhau của các Control 
Thuộc tính Mô tả 
Anchor Có 4 hƣớng đƣợc định nghĩa là: top, bottom, left, right để cố định 
(neo). Khi control chứa nó thay đổi kích thƣớc thì nó sẽ bị thay đổi 
kích thƣớc nếu nếu các hƣớng left / right / top / bottom bị cố định 
(neo). BackColor Màu nền của control. 
Bottom Là khoảng cách theo chiều dọc từ cạnh đáy của control đến cạnh 
trên của control chứa nó. 
Dock Giống nhƣ Anchor nhƣng việc cố định (neo) này theo một cạnh nào 
đó 
của control (hoặc cả 4 cạnh) với control chứa nó. Enabled Control đƣợc phép tƣơng tác (True) hay không đƣợc phép tƣơng 
tác 
(False)) với ngƣời dùng. ForeColor Màu chữ của control. 
Height Là chiều cao của control tính từ cạnh trên của control đến cạnh dƣới của 
control. 
Left Là khoảng cách theo chiều ngang từ cạnh trái của control đến cạnh trái 
của control chứa nó. 
Name Tên của control. 
Parent Chỉ đến control chứa control hiện hành. 
Right Là khoảng cách theo chiều ngang từ cạnh phải của control đến cạnh trái 
của control chứa nó. 
TabIndex Thứ tự focus khi nhấn phím Tab (trên bàn phím) của control so với các 
control khác cùng nằm trong control chứa nó. 
TabStop Chỉ định control có đƣợc phép “bắt” (True) / không đƣợc phép “bắt” 
(False) phím Tab. Nếu không đƣợc phép thì TabIndex cũng không dùng 
đƣợc. 
13 
Tag Là nhãn phân biệt giữa các control giống nhau trong cùng form. 
Text Nội dung hiện trong control. 
Top Là khoàng cách theo chiều dọc từ cạnh trên của control đến cạnh trên 
của control chứa nó. 
Visible Cho phép control hiện (True) / không hiện (False) khi chạy ứng dụng. 
Width Là chiều rộng của control tính từ cạnh trái của control đến cạnh phải của 
control. 
Xác định giá trị thuộc tính cho điều khiển, chọn điều khiển cần thiết lập thuộc tính, hiển thị cửa sổ 
Property (Nhấn phím F4, hoặc nhấn chuột phải, chọn Show property) , chọn biểu tƣợng thuộc tính của 
Control và thay đổi giá trị các thuộc tính theo nhu cầu. 
b. Methods (Phương thức) của control 
Mỗi một control có một tập các phƣơng thức, mà control có thể thực hiện đƣợc và có 
c. Events (Sự kiện) của control 
Sự kiện là những phản ứng của đối tƣợng. Nói cách khác, sự kiện là những tín hiệu phát ra khi 
ngƣời dùng thao tác trên đối tƣợng. Nhờ có event, ngƣời lập trình sẽ nhận đƣợc những tín hiệu và xử lý 
những tín hiệu đó để phản hồi lại cho ngƣời dùng, tạo nên sự nhịp nhàng cho chƣơng trình. 
Bảng sau trình bày một số sự kiện thƣờng dùng 
Sự kiện Mô tả 
Click Gọi đến khi control bị Click. Trong một vài control, event này cũng xảy 
ra khi ngƣời dùng nhấn phím Enter. 
DoubleClick Gọi đến khi control bị Double-Click. Trong một vài control, event này 
không báo giờ đƣợc gọi. Ví dụ: control Button. 
DragDrop Gọi đến khi việc “Drag and Drop” đƣợc hoàn tất. 
DragEnter Gọi đến khi đối tƣợng vừa đƣợc “Drag” đến biên của control. 
DragLeave Gọi đến khi đối tƣợng vừa đƣợc “Drag” ra ngoài biên của control. 
DragOver Gọi đến khi đối tƣợng đƣợc “Drag” bên trong control. 
KeyDown Gọi đến khi vừa bấm một phím bất kỳ từ 1 control đang focus. 
Sự kiện này luôn đƣợc gọi trƣớc sự kiện KeyUp. 
14 
KeyPress Gọi đến khi vừa bấm một phím bất kỳ từ 1 control đƣợc focus. 
Sự kiện này đƣợc gọi sau sự kiện KeyUp. 
KeyUp Gọi đến khi vừa bấm một phím bất kỳ rồi thả ra từ 1 control đang focus. 
Sự kiện này luôn đƣợc gọi sau sự kiện KeyDown. 
GotFocus Gọi đến khi control đƣợc focus. 
LostFocus Gọi đến khi control bị mất focus. 
MouseDown Gọi đến khi con trỏ chuột nằm trên 1 control và nút chuột đƣợc nhắp 
nhƣng chƣa thả ra. 
MouseMove Gọi đến khi con trỏ chuột đi qua 1 control. 
MouseUp Gọi đến khi con trỏ chuột nằm trên 1 control và nút chuột vừa đƣợc thả. 
Paint Gọi đến khi control đƣợc vẽ. 
Validated Gọi đến khi control focus, property CaucesValidation đƣợc đặt là true 
và sau khi gọi việc kiểm tra bằng Validating. 
Validating Gọi đến khi control mất focus, property CaucesValidation đƣợc đặt là 
true. 
Chọn sự kiện để viết mã lệnh cho control, chọn điều khiển cần thiết lập thuộc tính, hiển thị cửa sổ 
Property (Nhấn phím F4, hoặc nhấn chuột phải, chọn Show property), chọn biểu tƣợng sự kiện trên cửa 
sổ Property, sau đó chọn sự kiện của điều khiển cần thực hiện. 
 Chú ý: Để dừng chƣơng trình chúng ta sử dụng các câu lệnh sau 
this.Close(); // Đóng form hiện hành 
Application.Exit // Kết thúc ứng dụng 
15 
BÀI 2: MỘT SỐ ĐIỀU KHIỂN WINFORM (1) 
2.1. Label ( ) 
- Công dụng: Là điều khiển dùng để hiển thị tiêu đề hay văn bản mang tính mô tả, mà ngƣời dùng 
không thể thay đổi. Label dùng để định danh cho các điều khiển khác trên Form đƣợc gọi là 
Label mô tả. Label dùng để hiển thị kết quả đầu ra 
- Thêm label vào Form: Để thêm điều khiển Label vào Form ta chọn biểu tƣợng label trên thanh 
Toolbox, sau đó kéo thả vào form. Với các điều khiển khác cũng thực hiện tƣơng tự. 
- Thuộc tính hay dùng: 
Tên Ý nghĩa 
Text Giá trị hiển thị trên Label 
AutoSize Cho phép tự động thay đổi kích thƣớc của Label để 
vừa với nội dung 
BoderStyle Xác định hình dáng đƣờng viền của Label 
Font Tên Font, kiểu và kích thƣớc văn bản đƣợc hiển thị 
trên Label. 
Location Vị trí của Label trên form tƣơng ứng với góc bên 
trái của form 
Name Tên sử dụng để xác định Label. 
16 
Size Chỉ ra chiều rộng và chiều cao của Label 
TextAlign Chỉ ra cách căn văn bản trong Label 
- Xác định giá trị thuộc tính cho điều khiển Label (tƣơng tự cho các điều khiển khác): Chọn điều 
khiển, hiển thị cửa sổ Property (Nhấn phím F4, hoặc nhấn chuột phải, chọn Show property) và 
thay đổi giá trị các thuộc tính theo nhu cầu. 
2.2. TextBox( ) 
- Chức năng: Điều khiển Textbox cho phép bạn nhập và hiển thị dữ liệu. 
- Một số thuộc tính thƣờng dùng: 
Tên Ý nghĩa 
AcceptsTab Nhận một trong hai giá trị True hay False 
- True: Khi nhấn phím Tab thì con trỏ (Focus) chỉ 
di chuyển bên trong Textbox (Với điều kiện 
thuộc tính Multiline=True). 
- False: Khi nhấn Tab thì Focus di chuyển qua lại 
giữa các điều khiển trên Form 
→ Thuộc tính này hay đặt bằng True trong 
các ứng dụng soạn thảo văn bản 
ContextMenuStrip Chọn Menu ngữ cảnh khi nhấn chuột phải vào 
Textbox 
Font Chọn kiểu Font chữ cho Textbox 
HideSelection Nhận một trong hai giá trị True hay False 
- True: Không cho phép các thuộc tính: 
SelectionStartcó hiệu lực. 
- False: Ngƣợc lại 
MaxLenght Số lƣợng kí tự lớn nhất cho phép nhập vào Textbox 
Multiline Nhận một trong hai giá trị True hay False 
- True: Cho phép nhập và hiển thị giá trị của 
Textbox trên nhiều dòng (ngƣời dùng có thể 
nhìn thấy toàn bộ giá trị Text của nó) 
- False: Cho phép nhập/hiển thị giá trị của 
Textbox trên một dòng 
17 
PasswordChar Hiển thị giá trị của Textbox dƣới dạng các kí tự mà 
bạn thay thế (kí tự do ngƣời dùng nhập vào: *, #...) 
ReadOnly 
ScrollBars Cho phép hiển thị thanh trƣợt hay không? (Với điều 
kiện thuộc tính Multiline=True mới nhìn thấy thanh 
cuộn) 
TabIndex Đặt thứ tự cho phím tab 
Visible Cho phép Textbox hiển thị hay không? 
CanUndo Trả lại hai giá trị True/False. 
- True: có thể Undo lại đƣợc (nhƣ Word) 
- False: Ngƣợc lại 
Các thuộc tính SelectionText o SelectedText 
o SelectionStart 
o SelectionLength 
- Một số phương thức thường dùng: 
Tên Ý nghĩa 
AppendText Nối một chuỗi (string) vào giá trị Text hiện có của Textbox 
Copy 
Xử lý phần nội dung bôi đen (nhƣ Word) Cut 
Paste 
Focus Chuyển Focus (con trỏ) vào TextBox 
Clear Xóa toàn bộ Textbox 
Select Lấy ra một chuỗi trong Textbox (xem Code) 
SelectAll Lấy tất cả giá trị của Textbox 
Undo Xử lý Undo nhƣ Word 
2.3. Button ( ) 
- Công dụng: Dùng để thực thi lệnh. Khi nhắp chuột lên button, chƣơng trình nhận đƣợc tín hiệu 
Click và lệnh đƣợc thi hành. 
- Thuộc tính: 
18 
Thuộc tính Mô tả 
Text Nhập nội dung vào Button 
2.4. CheckBox ( ) 
- Công dụng: Cho phép ngƣời dùng chọn hoặc không chọn. 
- Thuộc tính: 
Thuộc tính Mô tả 
Checked Không có dấu check (False) / Có dấu check (True) 
- Minh họa: 
Minh họa thuộc tính Text của Textbox: 
private void btTextbox_Click(object sender, EventArgs e) 
 { //Trƣớc khi gán thuộc tính text 
 MessageBox.Show("Giá trị textbox trƣớc khi gán: "+ textBox1.Text); 
 //Gán giá trị Text 
 textBox1.Text = "Chào các bạn"; 
 //Sau khi gán 
MessageBox.Show("Giá trị textbox sau khi gán: " + textBox1.Tex 
 } 
Minh họa thuộc tính SelectedText 
private void btTextbox_Click(object sender, EventArgs e) 
{ 
 //Thuộc tính SelectedText lấy ra một chuỗi mà bạn bôi đen (Chọn) 
 //Bạn hãy bôi đen một vài từ trong Textbox sau đó Click vào Button này sẽ 
hiển thị 
 //Message thông báo từ bạn chọn 
 string str = textBox1.SelectedText; 
 MessageBox.Show("Từ bạn vừa chọn (bôi đen) là: "+str); 
 } 
Minh họa thuộc tính SelectionStart và SelectionLength 
 private void btTextbox_Click(object sender, EventArgs e) 
 { 
 //Thuộc tính này dùng trong tìm kiếm rất nhiều 
 //Thuộc tính SelectionStart: Ví trí bắt đầu Select 
 //Thuộc tính SelectionLength: Chiều dài của vùng lựa chọn 
19 
 //Chú ý: Đặt thuộc tính HideSelection=False 
//Ví dụ: Tìm kiếm xem giá trị của Textbox có từ nào là chào hay không. Nếu có thì nó 
tự Bôi đen từ đó 
 string str = "chào"; 
 int i; 
 i = textBox1.Text.LastIndexOf(str); 
 if (i >= 0) 
 { 
 textBox1.SelectionStart = i; 
 textBox1.SelectionLength = str.Length; 
 } 
 } 
Minh họa thuộc tính CanUndo và phƣơng thức Undo 
 private void btTextbox_Click(object sender, EventArgs e) 
 { 
 //Nếu có thể Undo (có nghĩa: Bạn phải gõ văn bản vào Textbox rồi sửa, xóa...) 
 //Mới có thể Undo lại đƣợc 
 if (textBox1.CanUndo) 
 textBox1.Undo(); 
 } 
Minh họa phƣơng thức Select 
private void btTextbox_Click(object sender, EventArgs e) 
 { 
 //Cú pháp chung: txtNoiDung.Select(Start, Length); 
 //Mục đích để lấy về một chuỗi từ từ vị trí nào và chiều dài của chuỗi dƣợc chọn (tất 
nhiên: bôi đen vùng này). 
 //-> Phƣơng thức này tƣơng đƣơng với sử dụng 2 thuộc tính SelectionStart và 
SelectionLength 
 //Ví dụ: 
 txtNoiDung.Select(10, 5); 
 // 2 câu lệnh này 
 //textBox1.SelectionStart = 10; 
20 
 //textBox1.SelectionStart = 5; 
 } 
Minh họa phƣơng thức AppendText 
 private void btTextbox_Click(object sender, EventArgs e) 
 { 
 //Giá trị Textbox trƣớc khi gọi phƣơng thức 
 MessageBox.Show("Trƣớc: "+textBox1.Text); 
 //Gọi phƣơng thức 
 textBox1.AppendText("Khoa CNTT - UTEHY"); 
 //Giá trị Textbox trƣớc khi gọi phƣơng thức 
 MessageBox.Show("Sau: " + textBox1.Text); 
 } 
Xử lý chỉ cho phép Textbox nhập số (sự kiện KeyPress của Textbox) – Cách 1 
private void txtNoiDung_KeyPress(object sender, KeyPressEventArgs e) 
 { 
 if (e.KeyChar >= '0' && e.KeyChar <= '9') 
 e.Handled = false;//Handled: Đƣợc xử lý 
 else 
 e.Handled = true; 
 } 
Xử lý chỉ cho phép Textbox nhập số (sự kiện KeyPress của Textbox) – Cách 2 
private void txtNoiDung_KeyPress(object sender, KeyPressEventArgs e) 
 { 
 if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar)) 
 e.Handled = true; 
 //Char.IsDigit(e.KeyChar) --> 
 //kiểm tra xem phím vừa nhập vào textbox có phải là ký tự số hay 
không, hàm này trả về kiểu bool 
 //Char.IsContro(e.KeyChar) --> 
 //kiểm tra xem phím vừa nhập vào textbox có phải là các ký tự điều 
khiển 
21 
 //(các phím mũi tên,Delete,Insert,backspace,space bar) hay không, 
mục đích dùng hàm này là để cho phép ngƣời dùng xóa số trong trƣờng hợp nhập sai. 
 } 
 Ví dụ : 
Khởi tạo một ứng dụng Windows Forms Application, lƣu với tên là Ví dụ 1 nhƣ sau: 
* Yêu cầu: 
- Nhập: 
+ Username vào TextBox Tên đăng nhập (Name: txtUser) 
+ Password vào TextBox Mật khẩu (Name: txtPass) 
- Chọn hoặc không chọn ô CheckBox Ghi nhớ (Name: chkNho) 
- Nhắp button Đăng nhập thì hiện ra hộp thông báo chứa Tên đăng nhập, Mật khẩu; Và 
“Bạn có ghi nhớ” (nếu chkNho có đánh dấu chọn). 
- Nhắp button Xóa thì xóa trống TextBox Tên đăng nhập và TextBox Mật khẩu, đồng 
thời di chuyển con trỏ vào txtUser. 
- Nhắp button Dừng thì dừng chƣơng trình. 
* Hƣớng dẫn: 
- Thiết kế Form nhƣ yêu cầu, trong đó form có các thuộc tính sau: 
+ AutoSize: True 
+ Font: Times New Roman 
+ Size: 12 
+ Text: Form Đăng Nhập 
+ Icon: logo.ico 
- Nhắp đúp vào button Đăng nhập, thêm đoạn code sau: 
string thongbao; 
thongbao = "Tên đăng nhập là: " ; 
thongbao += this.txtUser.Text ; 
thongbao += "\n\rMật khẩu là: " ; 
thongbao += this.txtPass.Text; 
if (this.chkNho.Checked==true) 
 { thongbao += "\n\rBạn có ghi nhớ.";} 
- Nhắp đúp vào button Xóa, thêm đoạn code sau: 
 this.txtUser.Clear(); 
22 
 this.txtPass.Clear(); 
 this.txtUser.Focus(); 
- Nhắp đúp vào button Dừng, thêm đoạn code sau: 
Application.Exit(); 
+ Có thể thay button Xóa bằng button Reset với đoạn code nhƣ sau: 
this.txtUser.ResetText(); 
this.txtPass.ResetText(); 
this.txtUser.Focus(); 
 Bài tập: 
1. - Thiết kế form nhƣ mẫu. 
(txtsSo1, txtSo2, txtKQ, btnCong, btnTru, btnNhan, btnChia, btnXoa) 
- Viết chƣơng trình làm các phép toán: cộng, trừ, nhân, chia cho các button btnCong, 
btnTru, btnNhan, btnChia. 
- Xóa: Xóa trắng các TextBox. 
- Thêm vào button Dừng (btnDung), khi nhắp vào btnDung thì dừng chƣơng trình. 
- Cải tiến: 
Khi nhắp button btnChia, nếu txtSo2 là 0 thì xuất hiện hộp thông báo lỗi rồi xóa trống 
txtSo2 và di chuyển con trỏ đến TextBox này. 
2. Viết chƣơng trình giải phƣơng trình bậc nhất: bx + c = 0 
(txtB, txtC, btnGiai, txtKQ) 
- Thêm vào button Dừng, khi nhắp vào button này thì dừng chƣơng trình. 
23 
3. Viết chƣơng trình giải phƣơng trình bậc hai: ax2 + bx + c = 0 
4. Viết chƣơng trình nhập vào: họ tên (txtHoTen), nữ (chkNu), điểm văn (txtVan), điểm 
toán (txtToan), điểm ngoại ngữ (txtNN). 
- Nhắp vào nút Tính (btnTinh) thì in ra điểm thấp nhất (txtDTN), điểm kết quả (txtDKQ), 
xếp loại (txtXL). Biết rằng: 
+ Điểm thấp nhất: txtDTN là điểm thấp nhất trong 3 điểm: văn, toán, ngoại ngữ. 
 + Điểm thêm: DThem = 0.5 nếu là nữ; DThem = 0 nếu là nam. 
+ Điểm kết quả: txtKQ = txtVan * 2 + txtToan * 2 + txtNN + DThem 
 + Xếp loại theo tiêu chuẩn: 
. Giỏi: nếu txtKQ >= 40 và txtDTN >= 7 
. Khá: nếu txtKQ >=35 và txtDTN >= 6 
. Trung bình: nếu txtKQ >= 25 và txtDTN >= 5 
 . Yếu: các trƣờng hợp còn lại 
- Nhắp vào nút Xóa (btnXoa) thì xóa hết các nội dung trong các TextBox. 
- Thêm vào button Dừng, khi nhắp vào button này thì dừng chƣơng trình. 
5. Viết chƣơng trình tạo một ứng dụng gồm: 
- Form1: Màn hình chính có 5 button: Bài tập 1 (btnBT1), Bài tập 2 (btnBT2), Bài tập 3 
(btnBT3), Bài tập 4 (btnBT4), Thoát (btnThoat). 
+ Khi nhắp vào Button Bài Tập 1: mở Form2 
+ Khi nhắp vào Button Bài Tập 2: mở Form3 
+ Khi nhắp vào Button Bài Tập 3: mở Form4 
+ Khi nhắp vào Button Bài Tập 4: mở Form5 
- Form2: thực hiện bài tập 1. Bổ sung Button Trở về để đóng Form2. 
- Form3: thực hiện bài tập 2. Bổ sung Button Trở về để đóng Form3. 
- Form4: thực hiện bài tập 3. Bổ sung Button Trở về để đóng Form4. 
- Form5: thực hiện bài tập 4. Bổ sung Button Trở về để đóng Form5. 
Điều khiển tập hợp: 
Là một kiểu dữ liệu dùng lƣu trữ nhiều phần tử có cùng đặc tính. Ví dụ: Mảng, Tập các nút lệnh 
chứa trên Form, tập các phần tử (Item) của Combobox, Listbox. 
Các thuộc tính, phƣơng thức lớp Collection 
 Count/Length: Lấy về số phần tử của tập hợp. 
 Add, AddRange: Thêm phần tử vào tập hợp. 
 Remove, RemoveAt: Xóa phần tử khỏi tập hợp. 
 Clear: Xóa toàn bộ các phần tử khỏi tập hợp. 
 Insert: Chèn một phần tử vào tập hợp (Khác với Add luôn thêm phần tử mới vào cuối tập 
hợp, Insert thêm vào một vị trí xác định nào đó trong tập hợp). 
 Items[i]: Lấy một phần tử thứ i trong tập hợp. 
24 
Duyệt các phần tử trong tập hợp 
Để duyệt các phần tử trong tập hợp ngƣời ta thƣờng sử dụng vòng lặp ForEarch 
foreach (biến in biến_Tập_hợp) 
{Xử lý giá trị lấy đƣợc} 
2.5. ListBox ( ) 
- Công dụng: Dùng để hiển thị một danh sách các lựa chọn. 
- Thuộc tính: 
Thuộc tính Mô tả 
Items Các mục giá trị trong ListBox 
SelectedItem Item đƣợc chọn 
Phƣơng thức Mô tả 
Add("chuỗi") Thêm một mục giá trị là "chuỗi" 
ToString() Trả về chuỗi ký tự đƣợc chọn 
* Nhập giá trị vào ListBox: .Items.Add ("Chuỗi") ; 
* Lấy giá trị trong ListBox: .SelectedItem.ToString() ; 
 Ví dụ: 
* Khởi tạo một ứng dụng Windows Forms Application, lƣu với tên là ViduListBox nhƣ sau: 
* Yêu cầu: 
- ListBox lstWeb (Liên kết website) chứa các giá trị: 
+ Tuổi trẻ 
+ Thanh niên 
+ VNExpress 
+ Dân trí 
+ Công an 
- TextBox txtKQ (chứa kết quả) để trống. 
25 
- Nhắp button btnOk (Ok) sẽ hiện trong txtKQ tên website đƣợc chọn ở lstWeb. 
- Nhắp button btnReset (Reset) sẽ xóa trống txtKQ. 
* Hƣớng dẫn: 
- Thiết kế Form nhƣ yêu cầu, trong đó form có các thuộc tính sau: 
+ AutoSize: True 
+ Font: Times New Roman 
+ Size: 12 
+ Text: FormWebLinks 
- Nhắp đúp vào button Ok rồi thêm đoạn code sau: 
this.txtKQ.Text = "Bạn đã chọn website "+ this.lstWeb.SelectedItem.ToString(); 
* Cải tiến: 
Chọn sự kiện FormLoad đƣa đoạn mã lệnh sau vào sự kiện. 
this.lstWeb.Items.Add("Tuổi trẻ"); this.lstWeb.Items.Add("Thanh niên"); 
this.lstWeb.Items.Add("VNExpress"); this.lstWeb.Items.Add("Dân trí"); 
this.lstWeb.Items.Add("Công an"); this.lstWeb.SelectedItem = "Tuổi trẻ"; 
2.6. ComboBox ( ) 
- Công dụng: Dùng để hiển thị một danh sách các lựa chọn / hoặc nhập vào một giá trị. 
- Thuộc tính: 
Thuộc tính Mô tả 
DisplayMember Gán nội dung thể hiện trên ComboBox 
Items Liệt kê các mục giá trị trong ComboBox 
SelectedItem Lấy Item đƣợc chọn 
SelectedText Lấy nội dung thể hiện trên ComboBox từ DisplayMember 
SelectedValue Lấy giá trị từ ValueMember 
ValueMember Gán giá trị cho ComboBox 
 Ví dụ: 
* Khởi tạo một ứng dụng Windows Forms Application, lƣu với tên là ViDuComboBox nhƣ sau: 
* Yêu cầu: 
Thực hiện giống nhƣ ViduListBox, nhƣng thay ListBox bằng ComboBox cbWeb. 
26 
2.7. RadioButton ( ) 
- Công dụng: Dùng để chọn một trong các lựa chọn trong danh sách. 
- Thuộc tính: 
Thuộc tính Mô tả 
Checked Không có dấu chọn (False) / Có dấu chọn (True) 
2.8. GroupBox ( ) 
- Công dụng: Tạo ra một nhóm. 
- Thuộc tính: 
Thuộc tính Mô tả 
BackgroundImage Hình nền 
BackgroundImageLayout None / Tile / Center / Stretch / Zoom 
 Ví dụ 
* Khởi tạo một ứng dụng Windows Forms Application, lƣu với tên là ViDuRadio nhƣ sau: 
* Yêu cầu: 
- Nhập họ và tên vào TextBox txtHoTen 
- Chọn kiểu chữ 
+ Radio Button (rad1): chữ thƣờng 
+ Radio Button (rad2): chữ HOA 
- Nhắp vào Button Kết quả (btnKQ) sẽ in họ và tên bằng kiểu chữ đƣợc chọn trong 
TextBox txtKQ. 
- Nhắp vào Button Xóa (btnXoa) sẽ xóa trống txtHoTen, txtKQ, rad1 đƣợc chọn và đƣa 
con trỏ vào ô TextBox txtHoTen. 
* Hƣớng dẫn: 
- Thiết kế Form nhƣ yêu cầu, trong đó form có các thuộc tính sau: 
+ AutoSize: True 
+ Font: Times New Roman 
+ Size: 12 
+ Text: Đổi kiểu chữ 
- Nhắp đúp vào nút Kết quả rồi thêm đoạn code sau: 
string hoten=this.txtHoTen.Text.Trim(); 
 if (this.rad1.Checked == true) 
 txtKQ.Text = hoten.ToLower(); 
 if (this.rad2.Checked == true) 
 txtKQ.Text = hoten.ToUpper(); 
- Nhắp đúp vào nút Xóa rồi thêm đoạn code sau: 
 this.txtHoTen.Clear(); 
27 
 this.txtKQ.Clear(); 
 this.rad1.Checked = true; 
 this.txtHoTen.Focus(); 
* Bổ sung: 
- Nhắp vào Button Dừng (btnDung) sẽ dừng chƣơng trình: thiết kế và viết code sau 
Application.Exit(); 
28 
BÀI 3. THỰC HÀNH 1 – CÁC ĐIỀU KHIỂN WINFORM (1) 
BÀI 4. MỘT SỐ ĐIỀU KHIỂN WINFORM (2) 
4.1. Timer ( ) 
- Công dụng: Quy định khoảng thời gian định kỳ để thực hiện một công việc. 
- Thuộc tính: 
Thuộc tính Mô tả 
Enabled Bật / tắt chế độ hẹn thời gian của điều khiển Timer 
Interval Khoảng thời gian định kỳ tính bằng đơn vị ms 
 Ví dụ: 
* Tạo một Form với tên HenGio nhƣ sau: 
* Yêu cầu: 
- Tạo Timer1 có Enabled = false; Interval = 1000 
- Khởi tạo biến đếm i = 20 
- Button Bắt đầu (btnBatDau): dùng để bật chế độ hẹn thời gian. 
- Button Dừng (btnDung): dùng để dừng chƣơng trình. 
- Timer1: Đếm ngƣợc từ 20 đến 1 và xuất ra dòng chữ “Hết giờ”. 
+ Xuất giá trị biến đếm i ra Label lblDongHo. 
+ Giảm biến i xuống 1 đơn vị. 
+ Khi biến đếm i < 0 thì tắt chế độ hẹn giờ và xuất “Hết giờ!” ra Label lblDongHo. 
* Hƣớng dẫn: 
Thiết kế Form nhƣ yêu cầu, trong đó form có các thuộc tính sau: 
+ AutoSize: True 
+ Font: Times New Roman 
+ Size: 12 
+ Text: Đồng hồ đếm ngƣợc 
- Khai báo biến đếm i: qua code, thêm đoạn code để đƣợc kết quả nhƣ sau: 
public Form1() 
{ 
InitializeComponent(); 
} 
int i = 10; 
- Nhắp đúp vào nút Bắt đầu rồi thêm đoạn code sau: 
this.timer1.Enabled = true; 
- Nhắp đúp vào nút Dừng rồi thêm đoạn code sau: 
Application.Exit(); 
- Nhắp đúp vào nút Timer1 (Timer1_Tick) rồi thêm đoạn code sau: 
this.lblDongHo.Text = i.ToString(); i--; 
if (i < 0) 
this.timer1.Enabled = false; 
29 
4.2. RichTextBox ( ) 
- Công dụng: Điều khiển RitchTextBox dùng để lƣu trữ và hiển thị văn bản theo nhiều định 
dạng khác nhau (định dạng chuẩn là rtf) 
Điều khiển RitchTextBox có rất nhiều các thuộc tính giống Textbox nói riêng 
và các điều khiển khác nói chung. Ý nghĩa của các thuộc tính này là giống nhau với 
các điều khiển. Ở đây chúng ta xét một số thuộc tính khác của RitchTextBox. 
- Thuộc tính: 
Thuộc tính Mô tả 
ReadOnly Không cho soạn thảo, chỉ đọc. 
SelectedText Lấy về chuỗi đƣợc lựa chọn (chuỗi mà chúng ta bôi đen) 
SelectionStart, 
SelectionLength 
Lấy về một chuỗi với vị trí bắt đầu và chiều dài, hai 
thuộc tính này thƣờng đi với nhau 
SelectionFont Lấy thông tin về Font của một chuỗi đƣợc lựa chọn (bôi đen) 
SelectionColor Lấy thông tin về Color của chuỗi đƣợc bôi đen đƣợc lựa chọn 
CanUndo Trả lại hai giá trị True/False. 
- True: có thể Undo lại đƣợc (nhƣ 
Word) 
- False: Ngƣợc lại 
CanRedo Tƣơng tự nhƣ thuộc tính CanUndo 
- Phƣơng thức thƣờng dùng 
Tên phƣơng thức Ý nghĩa 
AppendText Nối một chuỗi vào RitchTextBox 
Copy Xử lý phần nội dung bôi đen (nhƣ Word) 
Cut 
Paste 
Find Tìm kiếm một xâu trong RitchTextBox 
Focus Chuyển Focus vào RitchTextBox 
LoadFile Đọc nội dung một file vào RitchTextBox 
SaveFile Ghi nội dung của RitchTextBox ra file 
Select Lấy ra một chuỗi trong RitchTextBox (tƣơng tự 
TextBox) 
SelectAll Lấy tất cả nội dung của RitchTextBox 
Redo Xử lý Undo, Redo nhƣ Word 
30 
Undo 
4.3. PictureBox ( ) 
- Công dụng: Khung chứa hình ảnh. 
- Thuộc tính: 
Thuộc tính Mô tả 
Image Gán kiểu Image hiển thị trên PictureBox 
ImageLocal Gán đƣờng dẫn cho ảnh hiển thị trên PictureBox 
SizeModel Chọn kiểu kích thƣớc của PictureBox 
4.4. ImageList ( ) 
- Công dụng: Dùng để quản lý tập các Image (Image, Icon). Thƣờng sử dụng điều khiển 
ImageList với các điều khiển khác: ListView, TreeView, Toolbar, NotifyIcon 
- Thuộc tính: 
Thuộc tính Mô tả 
Images Chứa danh sách các Image. Có thể đƣa các Image hay Icon vào thông qua 
giao diện (Cửa sổ Properties) hay mã lệnh (Tập các Image trong 
ImageList là một Collection nên nó có đầy đủ các phƣơng thức của 
Collection). 
Truy xuất tới một Image trong ImageList theo cú pháp: 
Tên_ImageList.Images[Index]; 
ImageSize Kích cỡ của Image (Mặc định là 16x16) 
4.5. Image ( ) 
- Công dụng: Hiển thị ảnh với các định dạng khác nhau 
- Thuộc tính: 
Thuộc tính Mô tả 
Image Lựa chọn ảnh hiển thị trên nó 
 Ví dụ: 
* Tạo một Form với tên FrmPicture nhƣ sau: 
31 
* Yêu cầu: 
- Tạo PictureBox, và các Button nhƣ thiết kế 
- Button Xem (btnXem): dùng để hiển thị ảnh trong 1 đƣờng dẫn trên máy tính 
- Button Không xem (btnKhongXem): dùng để không hiển thị ảnh. 
* Hƣớng dẫn: 
Thiết kế Form nhƣ yêu cầu, trong đó form có các thuộc tính sau: 
- Trong sự kiện FormLoad viết câu lệnh sau 
private void FrmPicture_Load(object sender, EventArgs e) 
 { 
 pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; 
 } 
- Nhắp đúp vào nút Xem rồi thêm đoạn code sau: 
pictureBox1.ImageLocation = @"D:\TranhPC.jpg"; 
- Nhắp đúp vào nút Không Xem rồi thêm đoạn code sau: 
pictureBox1.ImageLocation =””; 
4.6. Điều khiển ListView ( ) 
- Công dụng: Điều khiển ListView dùng để trình bày các phần tử dạng danh sách với nhiều hình 
dạng khác nhau. 
- Một số khái niệm liên quan đến ListView 
32 
Minh họa về ListView 
Cột trong ListView 
33 
Khái niệm ColumnHeader 
Khái niệm ListViewItem 
34 
 Khái niệm SubItems 
Minh họa về Group 
- Một số thuộc tính thường dùng: 
Thuộc tính Mô tả 
CheckBoxes Nhận một trong hai giá trị True hay False (mặc định là False) 
- True: Hiển thị một checkbox bên cạnh phần tử 
đầu tiên của mỗi hàng (1 hàng = 1 ListviewItem) 
trong Listview 
35 
- False: Ngƣợc lại 
Columns Tập các cột trong ListView là một Collection. Thông qua thuộc 
tính này có thể thêm các cột vào Listview (Có thể thêm các cột 
vào Listview thông qua giao diện đồ họa hay có thể viết Code. 
Chú ý: Phải đặt thuộc tính View là Detail thì bạn mới có thể nhìn 
thấy các cột này) 
ContextMenuStrip Gắn một menu ngữ cảnh với điều khiển ListView (khi nhấn 
chuột phải vào Listview thì sẽ hiển thị menu này) 
FullRowSelect Nhận một trong hai giá trị True hay False 
- True: Cho phép chọn (bôi đen) cả hàng (của phần 
tử đang đƣợc chọn. Chú ý: Thuộc tính View = 
Detail) 
- False: Ngƣợc lại 
GridLines 
Nhận một trong hai giá trị True hay False 
- True: Hiển thị lƣới bao quanh và ngăn cách các 
hàng (Chỉ có hiệu lực nếu thuộc tính View = 
Detail) 
- False: Ngƣợc lại 
Group Khai báo nhóm để phân loại các phần tử sau khi trình bày trên 
điều khiển Listview 
HeaderStyle Đây là thuộc tính cho phép chọn Style cho Listview trong chế độ 
View là Report 
Items Là một Collection. Cho phép tạo ra các giá trị cho các hàng, cột 
trong Listview (tất nhiên có thể dùng giao diện đồ họa hay viết 
Code) 
LabelEdit Nhận một trong hai giá trị True hay False 
- True: Cho phép thay đổi (sửa) Text của các phần 
tử (các Ô). 
- False: Ngƣợc lại 
LabelWap Nhận một trong hai giá trị True hay False 
- True: Chuỗi DHSPKTHY sẽ tự động xuống hàng 
khi chiều dài không đủ để trình bày 
- False: Ngƣợc lại 
36 
MultiSelect Nhận một trong hai giá trị True hay False 
- True: Cho phép chọn nhiều hàng (ListviewItem). 
Mặc định là True 
- False: Không cho phép chọn nhiều hàng 
LargeImageList Đối tƣợng ImageList chứa danh sách các Image theo chỉ số 
(Index) từ 0 đến n-1. Đƣợc sử dụng nếu thuộc tính View là 
LargeIcon 
SmallImageList Đối tƣợng ImageList chứa danh sách các Image theo chỉ số 
(index) từ 0 đến n-1. Đƣợc sử dụng nếu thuộc tính View là 
SmallIcon 
Scrollable Nhận một trong hai giá trị True hay False 
- True: Cho phép xuất hiện thanh trƣợt trong 
Listview (Khi số ListViewItem nhiều và vƣợt qua 
chiều cao của ListView) 
- False: Ngƣợc lại 
Sorting Sắp xếp giá trị các hàng (ListViewItem) trong ListView (Chỉ có 
hiệu lực nếu thuộc tính View là Detail). Thuộc tính này nhận một 
trong các giá trị sau 
 None: Không Sắp xếp 
 Ascending: Sắp xếp tăng 
 Descending: Sắp xếp giảm 
SelectedItems Trả về danh sách các phần tử đƣợc chọn (bôi đen) 
CheckedItems Trả về danh sách các phần tử đƣợc check (tất nhiên thuộc tính 
CheckBoxes = True) 
View Các kiểu Hiển thị trên ListView. Thuộc tính View có thể nhận 
một số giá trị sau: 
 LargeIcon 
 SmallIcon 
 List 
 Detail 
 Title 
→ Mặc định là: LargeIcon 
37 
- Một số phương thức thường dùng: 
Tên Ý nghĩa 
Clear Xóa tất cả ListView 
RemoveAt Xóa bỏ một cột có chỉ số (ở vị trí) nào đó 
Remove Xóa các mục đƣợc chọn 
- Một số sự kiện thường dùng: 
Tên Ý nghĩa 
SelectedIndexChanged Xảy ra khi ngƣời sử dụng thay đổi phần tử đƣợc chọn trong 
ListView 
ItemActivate Xảy ra khi chọn phần tử trên ListView 
ItemChecked Khi Check vào biểu tƣợng Checkbox của mỗi phần tử trên 
điều khiển ListView 
Giả sử chúng ta có một form có tên: frmListView. Trên đó có chứa một số điều khiển sau: 
 Điều khiển ListView có tên listView1 (Chúng ta để tất cả các thuộc tính của listView1 với 
giá trị mặc định). 
 Button btCheck: minh họa việc duyệt các hàng đƣợc check trên ListView 
 Buttonbt RemoveAtColumns: Minh họa xóa một cột trong ListView 
 Buttonbt RemoveAtItems: Minh họa xóa một hàng trong ListView 
 Buttonbt ShowFile: Minh họa hiển thị tất cả các file trong một thƣ mục nên ListView 
 Button btGroup: Minh họa về Group trong ListView 
Chúng ta sẽ minh họa sử dụng ListView qua sự kiện Click của các button trên. 
Tạo các cột, hàng cho ListView bằng code 
 private void frmListView_Load(object sender, EventArgs e) 
 { 
 //Đặt một số thuộc tính cho điều khiển ListView1 bằng code 
 //Bạn chỉ có thể nhìn thấy các cột nếu đặt thuộc tính View=Detail 
 listView1.View = View.Details; 
 listView1.GridLines = true; 
 listView1.CheckBoxes = true;//Hiển thị checkbox: các bạn xem kết quả ở hinhg 
minh họa. 
 //Thêm 4 cột vào Listview 
 //Có thể thêm cột vào ListView theo cách này 
38 
 listView1.Columns.Add("Họ và tên", 100, HorizontalAlignment.Center); 
 listView1.Columns.Add("Quê quán", 100, HorizontalAlignment.Center); 
 listView1.Columns.Add("Lớp", 100, HorizontalAlignment.Center); 
 //Cách 2: Có thể thêm vào theo cách này: Sử dụng ColumnHeader 
 ColumnHeader ch = new ColumnHeader("chNgaySinh"); 
 ch.Text = "Ngày sinh"; 
 ch.TextAlign = HorizontalAlignment.Center; 
 ch.Width = 100; 
 listView1.Columns.Add(ch); 
 //Thêm hàng thứ nhất vào ListView 
 string[] Them = new string[] { "Nguyễn Văn Hải", "Hƣng Yên", "TK4N1", "29-
03-1987" }; 
 ListViewItem lv = new ListViewItem(Them); 
 listView1.Items.Add(lv); 
 //Thêm hàng thứ 2 
 string[] Them2 = new string[] { "Nguyễn Văn Hạnh", "Hà Nội", "TK4N1", "24-
04-1987" }; 
 ListViewItem lv2 = new ListViewItem(Them2); 
 listView1.Items.Add(lv2); 
 //Thêm hàng thứ 3 
 string[] Them3 = new string[] { "Phạm Thị Hạnh", "Hải Dƣơng", "TK4N1", "04-
10-1988"}; 
 ListViewItem lv3 = new ListViewItem(Them3); 
 listView1.Items.Add(lv3); 
 //Thêm hàng thứ 4 
 string[] Them4 = new string[] { "Vũ Thị Hảo", "Bắc Ninh", "TK4N1", "25-12-
1987" }; 
 ListViewItem lv4 = new ListViewItem(Them4); 
 listView1.Items.Add(lv4); 
 } 
→ Sau khi chạy có hình nhƣ sau: 
39 
Duyệt xem những hàng nào đƣợc Check 
private void btCheck_Click(object sender, EventArgs e) 
 { 
 //Bạn phải tạo ra một Listview nhƣ mục 7.1 trƣớc đã 
 MessageBox.Show("Tên các sinh viên đƣợc Check 
là","Check",MessageBoxButtons.OK); 
 //Duyệt các phần tử đƣợc Check thông qua thuộc tính CheckedItems 
 foreach (ListViewItem lvi in listView1.CheckedItems) 
 { 
 //Lấy về phần tử thứ mấy (ô thứ mấy) của ListViewItem (của 1 hàng): sử dụng 
SubItems 
 //DataGridView ListView 
 MessageBox.Show(lvi.SubItems[0].Text); 
 } 
 //Giờ thì bạn chạy và check thử vài hàng để thấy rõ kết quả 
 } 
Xóa một Cột tại vị trí nào đó 
 private void btRemoveAtColumns_Click(object sender, EventArgs e) 
 { 
 //Chú ý: Tập các column trong Listview là một Collection nên có đầy đủ các phƣơng thức 
của một Collection. 
 //Ví dụ: Xóa một cột ở vị trí nào đó 
 listView1.Columns.RemoveAt(1); 
 //Giờ thì bạn chạy và nhấn vào Button này để thấy kết qủa để xem các kết quả 
 } 
40 
Hình 7.2: Columns ↔ Collection 
Xóa một hàng tại một vị trí nào đó 
→ Hoàn toàn tƣơng tự nhƣ xóa một cột 
 private void btRemoveAtItems_Click(object sender, EventArgs e) 
 { 
 //Chú ý: Tập các Items trong Listview là một Collection nên có đầy đủ các phƣơng thức 
của một Collection. 
 //Ví dụ: Xóa một cột ở vị trí nào đó (tất nhiên bạn phải tạo ra một listview với các giá trị 
nhƣ mục 7.1) 
 listView1.Items.RemoveAt(1); 
 //Giờ thì bạn chạy và nhấn vào Button này để xem các kết quả 
 } 
Duyệt tất cả các file trong một thƣ mục và hiển thị nên ListView 
41 
 private void btShowFile_Click(object sender, EventArgs e) 
 { 
 //Listview (listView1) này hiển thị tất cả các File trong C:\WINDOWS 
 //Bạn có thể dùng hộp thoại FolderBrowserDialog để duyệt file trong thƣ mục bất kì mà 
bạn chọn 
 //Phƣơng thức Clear xóa toán bộ Listview 
 listView1.Clear(); 
 //Chọn một số thuộc tính cho Listview thông qua mã lệnh 
 listView1.View = View.Details; 
 listView1.FullRowSelect = true;//Cho phép chọn cả hàng nhƣ hình kết quả dƣới 
 listView1.GridLines = true; 
 //Add các cột vào Listview bằng mã lệnh 
 //Mỗi file có các đặc tính của file: Tên, kích thƣớc, kiểu file (ReadOnly, System...) nên chúng ta 
tạo ra các cột tƣơng ứng 
 listView1.Columns.Add("Number", 100, HorizontalAlignment.Left); 
 listView1.Columns.Add("Name", 300, HorizontalAlignment.Left); 
 listView1.Columns.Add("Size", 150, HorizontalAlignment.Left); 
 listView1.Columns.Add("Type", 100, HorizontalAlignment.Left); 
 //Nên khai báo đổi tƣợng DirectoryInfo để duyệt file 
 //DirectoryInfo là một lớp nằm trong System.IO 
 DirectoryInfo dir = new DirectoryInfo(@"C:\WINDOWS"); 
 //Khai báo i để lấy về Số thứ tự file: 1, 2, 3.... 
 int i = 0; 
 //Khai báo một ListviewItem - Một Hàng 
 ListViewItem lvi; 
 //Duyệt File () 
 foreach (FileInfo f in dir.GetFiles("*.*")) 
 { 
 //Tăng giá trị i nên 1 
 i++; 
 //Gán các thành phần cho lvi qua thuộc tính SubItems.Add 
42 
 lvi = new ListViewItem(i.ToString()); 
 lvi.SubItems.Add(f.Name); 
 lvi.SubItems.Add(f.Length.ToString()); 
 lvi.SubItems.Add(f.Attributes.ToString()); 
 //Sau khi đã gán phải Add vào Listview 
 listView1.Items.Add(lvi); 
 } 
 //Hết 
 } 
Kết quả sau khi nhấn vào Button Show File 
Làm việc với Group trong ListView 
private void btGroup_Click(object sender, EventArgs e) 
 { 
 //Ý tƣởng: Chúng ta muốn đƣa tất cả các file có cùng thuộc tính vào một nhóm 
 //làm việc với nhóm các bạn chú ý đối tƣợng ListViewGroup 
 //Xóa Listview trƣớcđã 
 listView1.Clear(); 
 //Đặt một số thuộc tính bằng Code 
 listView1.View = View.Details; 
 //Khai báo 3 nhóm 
 ListViewGroup gArchive; 
 ListViewGroup gSystem; 
 ListViewGroup gNormal; 
 //Add các cột vào Listview bằng mã lệnh 
43 
 listView1.Columns.Add("Number", 100, HorizontalAlignment.Left); 
 listView1.Columns.Add("Name", 300, HorizontalAlignment.Left); 
 listView1.Columns.Add("Size", 150, HorizontalAlignment.Left); 
 listView1.Columns.Add("Type", 100, HorizontalAlignment.Left); 
 //Add 3 nhóm - Group vào Listview 
 gArchive = new ListViewGroup("Archive"); 
 gSystem = new ListViewGroup("System"); 
 gNormal = new ListViewGroup("Normal"); 
 listView1.Groups.Add(gArchive); 
 listView1.Groups.Add(gSystem); 
 listView1.Groups.Add(gNormal); 
 //Listview này hiển thị tất cả các File trong C:\WINDOWS 
 //Nên khai báo đổi tƣợng DirectoryInfo 
 DirectoryInfo dir = new DirectoryInfo(@"C:\WINDOWS"); 
 //Khai báo i để lấy về Số thứ tự file: 1, 2, 3.... 
 int i = 0; 
 string ThuocTinhFile = ""; 
 //Khai báo một ListviewItem-Một Hàng 
 ListViewItem lvi; 
 //Duyệt file và đƣa vào Group các file cùng thuộc tính 
 foreach (FileInfo f in dir.GetFiles("*.*")) 
 { 
 i++; 
 //Gán các thành phần cho lvi qua thuộc tính SubItems.Add 
 lvi = new ListViewItem(i.ToString()); 
 lvi.SubItems.Add(f.Name); 
 lvi.SubItems.Add(f.Length.ToString()); 
 //Lấy về thuộc tính tập tin và xử lý 
 ThuocTinhFile = f.Attributes.ToString(); 
 lvi.SubItems.Add(ThuocTinhFile); 
 //Nhóm tập tin Archive 
 if (ThuocTinhFile.StartsWith("Archive")) 
 gArchive.Items.Add(lvi); 
44 
 //Nhóm tập tin Archive 
 if (ThuocTinhFile.StartsWith("System")) 
 gSystem.Items.Add(lvi); 
 //Nhóm tập tin Archive 
 if (ThuocTinhFile.StartsWith("Normal")) 
 gNormal.Items.Add(lvi); 
 //Sau khi đã gán phải Add vào Listview 
 listView1.Items.Add(lvi); 
 } 
 //Hết- Kết quả xem hình dƣới 
 } 
Group 
Lấy về giá trị của một ô (SubItems) bất kì nào đó trên ListView (sự kiện listView1_ItemActivate). 
 Giả sử chúng ta có hình nhƣ sau: 
45 
 Chúng ta muốn lấy thông tin về sinh viên “Phạm Thị Hạnh” bạn có thể sử dụng đoạn code 
sau: 
 private void listView1_ItemActivate(object sender, EventArgs e) 
 { 
 ListViewItem lvi = listView1.FocusedItem; 
 MessageBox.Show(lvi.Text);//Lấy ra giá trị ô text đầu tiên 
 //Lấy về cột thứ 1 - Cột Quê quán (Cột trông ListView có chỉ số bắt đầu = 0) 
 string Cot1 = lvi.SubItems[1].Text; 
 MessageBox.Show("Giá trị cột thứ 1: " + Cot1); 
 //Lấy về cột thứ 2 - Cột Lớp 
 string Cot2 = lvi.SubItems[2].Text; 
 MessageBox.Show("Giá trị cột thứ 2: " + Cot2); 
 //Giờ thì bạn chạy và Click vào một hàng xem để xem kết quả 
 //Ứng dụng: Thƣờng ứng dụng trong lập trình CSDL: Hiển hị tất cả các các thông tin (sinh 
viên chả hạn) 
 //nên ListView. khi ngƣời dùng chọn một hàng trên ListView thì hiển thị các giá trị tƣơng 
ứng nên 
 //Các Textbox. khi đó bạn có thể chỉnh sửa các thông tin và Update vào CSDL.... 
 //................ 
 } 
4.7. Treeview ( ) 
- Công dụng: Cho phép hiển thị dữ liệu ở dạng phân cấp. 
Có ba kiểu node: Root, Parent, Leaft. Một đối tƣợng TreeView đƣợc tạo ra mỗi khi 1 TreeView 
đƣợc đặt lên Form 
- Thuộc tính: 
+ ImageList: Gán đối tƣợng ImageList cho các biểu tƣợng hiển thị ở các nút 
+ Nodes: Danh sách các Node của đối tƣợng TreeView 
Ví dụ: TreeNode t = treeView1.Nodes[i]; 
+ SelectedNode: Nút đƣợc chọn hiện tại 
 Ví dụ: TreeNode t= treeView1.SelectedNode; 
- Phương thức 
+ GetNodeAt: Truy xuất đến một nút ở một vị trí xác định trong TreeView 
+ GetNodeCount: Tổng số nút trong cây 
- Sự kiện 
 + BeforeSelect, AfterSelect: Xảy ra trƣớc/sau khi một nút đƣợc chọn 
+ BeforeCollapse, AfterCollapse: xảy ra trƣớc/sau khi thu hẹp 1 nút. 
+ BeforeExpand, AfterExpand: xảy ra trƣớc/sau khi 1 mở rộng 1 nút. 
46 
Ví dụ: Xây dựng ứng dụng hiển thị dƣới dạng nhƣ sau: 
+ Yêu cầu: 
- Hiển thị 10 khách hàng, mỗi khách hàng có 5 đơn hàng. 
- Thiết kế lớp Customer và lớp Order 
- Tạo Treeview và hiển thị 
+ Hướng dẫn: 
- Cài đặt các lớp đối tƣợng 
47 
- Load các đối tƣợng lên TreeView 
4.8. DataGridView 
- Công dụng : Dùng để hiển thị dữ liệu dạng bảng, điều khiển thuộc nhóm các điều khiển 
cơ sở dữ liệu. Nhóm điều khiển này là những điều khiển cho phép lấy và hiển thị dữ liệu từ 
nguồn cơ sở dữ liệu: nhƣ điều khiển ComboBox, Listbox, DataGridView. Các điều khiển có 
thuộc tính DataSource để gán nguồn dữ liệu. Gắn nguồn cơ sở dữ liệu sẽ đƣợc trình bày trong 
phần về lập trình CSDL. Một DataGridView tƣơng ứng với cấu trúc của một mảng hai chiều 
gồm có các Column(cột), Row (hàng), Cell (ô). 
- Một số thuộc tính: 
- Thuộc tính Rows: trả về tập hợp các hàng trong dataGridView, một Row là một ListViewItem. 
48 
- Thuộc tính Columns: trả về tập tất cả các Column của DataGridView, một Column tƣơng ứng là 
một cột. 
- Thuộc tính Cells, là tập các ô của một hàng trong DataGridView. 
→ Có 2 cách để truy xuất đến một ô (để lấy giá trị) trong DataGridView (các bạn 
chú ý hai câu lệnh này) 
Cách 1: Tên_DataGridView[Chỉ_số_cột, Chỉ_số_hàng].Value 
Cách 2: Tên_DataGridView.Rows[Chỉ_số_hàng].Cells[Chỉ_số_Cột].Value 
- Thuộc tính thường dùng 
Thuộc tính Mô tả 
AutoSizeColumnsMode Các kiểu lựa chọn với Cột (Đặt các chế độ khác 
nhau) 
AutoSizeRowsMode Các kiểu lựa chọn với Hàng (Đặt các chế độ khác 
nhau) 
49 
Columns Làm việc với cột (Đặt tiêu đề cho Headers, lựa 
chọn kiểu cột (Checkbox, Button, Image). → 
Trong DataGridView một cột có thể là: Cột các 
Button, Cột các Checkbox 
DataMember Chọn cơ sở dữ liệu để hiển thị nên DataGridView 
DataSource Chọn nguồn dữ liệu cho DataGridView (hai thuộc 
tính DataSource và DataMember hay đi với nhau) 
GridColor Chọn màu cho lƣới (các hàng, các cột đƣợc ngăn 
cách nhau bởi lƣới) 
MultiSelect Cho phép/Không cho phép chọn nhiều dòng? 
ReadOnly Nhận một trong hai giá trị True hay False 
- True: Cho phép thay đổi giá trị các các 
phần tử (các ô hay các Cell). 
- False: không cho phép thay đổi giá trị 
các phần tử. 
- Sự kiện thường dùng 
CellClick: Xảy ra khi ngƣời dùng nhấn chọn một cell nào đó trên DataGridview. 
 Ví dụ: 
* Tạo form có tên frmGridView nhƣ sau: 
* Yêu cầu: 
- Khi FormLoad, thêm vào GridView 3 cột Mã SV, Họ tên, Quê quán. Trong đó cột Quê Quán có 
kiểu Combobox. 
- Khi ngƣời dùng nhập các giá trị trên các TextBox, nhấn vào Button Nhập: Thêm thông tin sinh 
viên xuống DataGridView. 
- Khi ngƣời dùng chọn một dòng trên DataGridView hiển thị thông tin tƣơng ứng vào các điều 
khiển. 
50 
- Khi ngƣời dùng sửa thông tin và nhấn vào nút sửa, thì sửa thông tin dòng đƣợc chọn trên 
DataGridView. 
- Khi ngƣời dùng nhấn nút Xóa, xóa các dòng đƣợc chọn trên DataGridView. 
- Khi ngƣời dùng nhấn nút tìm, nếu tìm thấy sinh viên có mã nhập vào trên TextBox mã sinh viên, 
thì chuyển con trỏ lựa chọn trên DataGridView đến dòng tìm đƣợc. 
- Khi ngƣời dùng nhấn nút kết thúc, thì đóng ứng dụng. 
* Hƣớng dẫn: 
- Trong sự kiện FormLoad viết các lệnh sau cho phép thêm cột vào DataGridView 
 private void GridView_Load(object sender, EventArgs e) 
 { 
 // Thêm cột dạng text 
 dataGridView1.Columns.Add("MaSV","Mã SV"); 
 dataGridView1.Columns.Add("TenSV", "Tên SV"); 
 // Thêm cột kiểu combobox 
 DataGridViewComboBoxColumn b = new DataGridViewComboBoxColumn(); 
 b.Items.Add("Hƣng yên"); 
 b.Items.Add("Hà Nội"); 
 b.Items.Add("Hải phòng"); 
 b.HeaderText = "Quê quán"; 
 dataGridView1.Columns.Add(b); 
} 
- Trong sự kiện click của button Nhập thêm mã lệnh sau cho phép thêm dòng vào DatagridView 
 private void butNhap_Click(object sender, EventArgs e) 
 { 
 //dataGridView1.Rows.Add(txtMaSV.Text, txtHoTen.Text); 
 dataGridView1.Rows.Add(txtMaSV.Text, txtHoTen.Text, txtQueQuan.Text); 
 txtMaSV.Text = ""; 
 txtHoTen.Text = ""; 
 txtQueQuan.Text = ""; 
 txtMaSV.Focus(); } 
- Khi chọn một sinh viên trên DataGridView thông tin sinh viên đƣợc hiển thị trên các điều khiển, 
viết lệnh trong sự kiện cellClick 
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) 
 { 
 int i = dataGridView1.CurrentRow.Index; // Lấy chỉ số dòng hiện tại 
 txtMaSV.Text = dataGridView1.Rows[i].Cells["MaSV"].Value.ToString(); 
 txtHoTen.Text = dataGridView1.Rows[i].Cells[1].Value.ToString(); 
 txtQueQuan.Text = dataGridView1.Rows[i].Cells[2].Value.ToString(); 
 } 
51 
- Nhấn double chuột vào nút sửa, viết mã lệnh sau: 
private void butSua_Click(object sender, EventArgs e) 
 { 
Int dong= dataGridView1.CurrentRow.Index ; // Dòng hiện tại đƣợc chọn 
 dataGridView1.Rows[dong].Cells[0].Value = txtMaSV.Text; // Gán giá trị mới 
 dataGridView1.Rows[dong].Cells[1].Value = txtHoTen.Text; 
 dataGridView1.Rows[dong].Cells[2].Value = txtQueQuan.Text; 
 } 
- Nhấn double chuột vào nút xóa, viết mã lệnh 
private void butXoa_Click(object sender, EventArgs e) 
 { 
 int dong = dataGridView1.CurrentRow.Index; 
 dataGridView1.Rows.RemoveAt(dong); // Cho phép xóa dòng có chỉ số truyền vào 
 } 
52 
BÀI 5: THỰC HÀNH 2 – CÁC ĐIỀU KHIỂN WINFORM (2) 
BÀI 6: MỘT SỐ ĐIỀU KHIỂN WINFORM (3) 
6.1. MenuStrip 
6.1. 1. MenuStrip ( ) 
- Công dụng: Điều khiển MenuStrip cho phép thiết kế hệ thống menu trên Form (menu một cấp 
hay nhiều cấp). Ví dụ hệ thống menu của chƣơng trình Word, Visual Studio 2008.MenuStrip 
cho phép thiết kế menu với các điều khiển: 
 ToolStripSeparator (Gạch phân cách) 
 ToolStripMenuItem (Menu con). 
 ToolStripCombobox (Combobox). 
- Tạo MenuStrip 
 Nhắp đúp vào control . 
 Nhập các menu con theo yêu cầu 
- Thuộc tính MenuStrip: 
Thuộc tính Mô tả 
TextDirection Chọn hình thức trình bày Menu (quay ngƣợc, quay 900) 
Items Thêm các menu con, kiểu của menu (Menu con, Textbox, 
Combobox, gạch phân cách). Thông qua giao diện đồ họa bạn 
có thể thêm các menu vào (tập các Items này là một 
Colleciton). 
RightToLeft Nhận một trong hai giá trị Yes hay No 
- Yes: trình bày menu từ phải qua trái 
- No: trình bày menu từ trái qua phải 
- Thuộc tính ToolStripItem 
Thuộc tính Mô tả 
Checked Nhận một trong hai giá trị True hay False 
- True: cho phép xuất hiện biểu tƣợng Checkbox 
53 
bên cạnh chuỗi Text của ToolStripMenuItem 
- False: Ngƣợc lại 
CheckOnClick Nhận một trong hai giá trị True hay False 
- True: Biểu tƣợng Checkbox xuất hiện bên cạnh 
chuỗi Text của ToolStripMenuItem (MenuItem) 
mỗi khi ngƣời dùng Click chọn vào nó 
- False: Ngƣợc lại 
CheckState Trạng thái của Checkbox bên cạnh chuỗi Text của menu. Và 
nhận một trong 3 giá trị: UnChecked, Checked, Indeterminate 
(Chú ý: Thuộc tính Checked=True thì thuộc tính này mới có 
hiệu lực. Hiển nhiên rồi phải không? ☺) 
DisplayStyle Hình thức trình bày của Menu và nhận một trong 4 giá trị 
- None: Không hiển thị gì cả (Text và Image) 
- Text: Chỉ cho phép xuất hiện chuỗi mô tả 
- Image: Chỉ cho phép xuất hiện ảnh( hoặc Icon) 
bên cạnh Text (xuất hiện ở phía ngoài cùng bên 
trái) 
- ImageAndText=Image+Text 
Image Hình ảnh xuất hiện bên cạnh chuỗi Text (chuỗi khai báo bên 
trong thuộc tính Text của MenuItem) 
ImageScaling Chọn hình thức trình bày của ảnh xuất hiện bên cạnh chuỗi. Và 
nhận một trong hai giá trị 
- None: BÌnh thƣờng 
- SizeToFit: Hiển thị đúng kích cỡ của Image hay 
Icon. 
ShortcutKeyDisplayString Chuỗi trình bày ứng với phím tắt mô tả cho MenuItem đó (Nối 
vào Text của MenuItem ví dụ: Open Ctrl+O) 
ShortcutKeys Chọn tổ hợp phím tắt ứng với MenuItem đó 
ShowShortcutKeys Nhận một trong hai giá trị True hay False 
- True: Cho phép trình bày chuỗi tổ hợp phím tắt 
của MenuItem (=True thì thuộc tính 
ShortcutKeyDisplayString mới có hiệu lực). 
- False: Ngƣợc lại 
Text Chuỗi trình bày MenuItem, bạn có thể sử dụng kí tự & trƣớc 
kí tự để sử dụng với phím Alt (phím nóng - phím tắt) 
TooltipText Chuỗi trợ giúp khi ngƣời dùng di chuyển chuột đến điều khiển 
MenuItem đó 
Visible 
6.1.2. Điều khiển ContextMenuStrip 
- Công dụng: 
54 
 Điều khiển ContextMenuStrip dùng để thiết kế menu popup (menu ngữ cảnh – menu xuất hiện 
khi ngƣời dùng nhấn chuột phải. Ví dụ: khi ngƣời dùng nhấn chuột phải vào Desktop xuất hiện một menu 
– đó chính là menu ngữ popup) . 
Để xuất hiện các menu Popup khi ngƣời dùng nhấn chuột phải vào các điều khiển (form, button, 
label, textbox) bạn chỉ cần khai báo thuộc tính ContextMenuStrip của các điều khiển đó là một điều 
khiển ContextMenuStrip. 
Điều khiển ContextMenuStrip cho phép thiết kế menu với các điều khiển sau (tƣơng tự nhƣ điều 
khiển MenuStrip). 
 ToolStripSeparator (Gạch phân cách) 
 ToolStripMenuItem (Menu con). 
 ToolStripCombobox (Combobox). 
 ToolStripTextbox (Textbox) 
- Một số thuộc tính thường dùng: 
Thuộc tính Mô tả 
Items Thêm các mnu con, kiểu của menu (Menu con, Textbox, 
Combobox, gạch phân cách). Thông qua giao diện đồ họa bạn 
có thể thêm các menu vào (Collection) 
RightToLeft Nhận một trong hai giá trị True hay False 
- True: Trình bày menu từ phải qua trái (căn lề là bên 
phải) 
- False: Trình bày menu từ trái qua phải (căn lề là bên 
trái) 
ShowImageMargin Hiển thị phần hình ảnh? 
 Ví dụ 
 Tạo một Form với tên FrmContextMenuStrip nhƣ sau: 
* Yêu cầu: Khi ngƣời dùng nhấn vào mỗi mục thì thay đổi màu nền của Form thành màu tƣơng 
ứng 
* Hƣớng dẫn 
55 
- Tạo Form nhƣ trên. 
- Tạo Menu ContextMenuStrip với các Item 
- Mở cửa sổ Property của Form, xác định giá trị cho thuộc tính ContextMenuStrip là điều khiển 
ContextMenuStrip vừa tạo 
- Viết lệnh sau trong sự kiện Click của StripMenuItem (Viết lệnh trên các sự kiện click của Menu 
khác tƣơng tự) 
private void đỏToolStripMenuItem_Click(object sender, EventArgs e) 
 { 
 this.BackColor = Color.Red; 
 } 
6.1.3. ToolStrip ( ) 
- Công dụng: Tạo ra toolbar cho form 
- Tạo ToolStrip: 
• Chọn công cụ 
• Kéo control ToolStrip vào trong form. 
• Bấm vào ToolStrip vừa tạo, ta có thể tạo ra các tool (công cụ) nhƣ: Label, 
TextBox, Button, ComboBox, DropDownButton. 
 Ví dụ : 
* Tạo ứng dụngWindows Forms Application nhƣ hình. 
* Hƣớng dẫn: dùng RichTextBox, MenuStrip và ToolStrip. 
6.2. Các điều khiển hộp thoại 
Các điều khiển hộp thoại cho phép tạo ra các hộp thoại cho ứng dụng. Khi chúng ta thực hiện 
muốn điều khiển hộp thoại đƣợc hiển thị nên, chúng ta sử dụng phƣơng thức ShowDialog(). 
56 
6.2.1. FontDialog ( ) 
- Công dụng: Tạo ra hộp thoại Font chữ cho ứng dụng 
- Các thuộc tính thường dùng: 
Thuộc tính Mô tả 
Color Trả về màu đƣợc chọn trong hộp thoại 
Font Trả về font chữ đƣợc chọn trong hộp thoại 
ShowColor Nhận giá trị True cho phép hiển thị bảng màu, false không 
hiển thị bảng màu 
6.2.2. OpenFileDialog ( ) 
- Công dụng: Điều khiển OpenFileDialog cho phép bạn chọn (select) tập tin đang tồn tại trên hệ 
thống, kiểm tra xem một tập tin có tồn tại hay không. Trong trƣờng hợp bạn có nhu cầu chọn 
một Foder (chứ không phải File) thì bạn chọn điều khiển FolderBrowserDialog 
Ví dụ: Hộp thoại mở ra khi chúng ta chọn File → Open của chƣơng trình Word hay Notepad 
- Thuộc tính thường dùng; 
Thuộc tính Mô tả 
AddExtension Nhận một trong hai giá trị True hay False 
- True: Cho phép thêm vào tên mở rộng (.txt, .jpg) vào 
file 
- False: Ngƣợc lại 
CheckFileExists Nhận một trong hai giá trị True hay False 
- True: Xuất hiện hộp cảnh báo nếu bạn nhập vào một tên 
file không tồn tại (nhập vào ô File name: trên hộp thoại 
OpenFileDialog ) 
- False: Ngƣợc lại 
CheckPathExists Nhận một trong hai giá trị True hay False 
- True: Kiểm tra đƣờng dẫn tới file có hợp lệ hay không 
trƣớc khi trả về. 
- False: Ngƣợc lại 
DefaultExt Chọn tên mở rộng cho file (.txt, .jpg) mặc định nếu ngƣời 
dùng không cung cấp tên mở rộng cho tập tin. 
Filter Chọn bộ lọc cho hộp thoại (Chỉ chọn File nào). Ví dụ: 
File Text (*.txt)|*.txt| Word File (*.doc)|*.doc; 
FilterIndex Chọn số thứ tự cho bộ lọc (bộ lọc sẽ hiển thị trong mục Files 
Of Types) 
FileName Set or Get tên tệp tin bạn chọn 
FileNames Set or Get mảng chứa tệp tin chọn (trong trƣờng hợp chọn 
nhiều tập tin) 
57 
InitialDirectory Đƣờng dẫn mặc định khi hộp thoại OpenFileDialog mở ra 
Multiselect Nhận một trong hai giá trị True hay False 
- True: Cho phép bạn chọn nhiều tập tin (ví du: Chọn nhiều 
bản nhạc để nghe) 
- False: Ngƣợc lại 
ReadOnlyChecked Nhận một trong hai giá trị True hay False 
- True: Check vào hộp thoại Checkbox Open as Read-Only 
bên dƣới Combobox Files Of Types 
- False: Ngƣợc lại (☻) 
(với điều kiện thuộc tính ShowReadOnly = True) 
RestoreDirectory Nhận một trong hai giá trị True hay False 
- True: Mở lại thƣ mục vừa mở ra lần trƣớc, với điều kiện 
thuộc tính InitialDirectory không đặt gì 
- False: Không mở lại thƣ mục vừa mở lần trƣớc 
ShowReadOnly Nhận một trong hai giá trị True hay False 
- True: Xuất hiện hộp Checkbox Open as Read-Only bên 
dƣới Combobox Files Of Types 
- False: Ngƣợc lại 
Title Đặt tiêu đề (xuất hiện trên Titlebar) cho hộp thoại 
OpenFileDialog 
6.2.3. SaveFileDialog ( ) 
- Công dụng: Tạo ra hộp thoại Save File. 
- Thuộc tính thường dùng: 
Thuộc tính Mô tả 
AddExtension Nhận một trong hai giá trị True hay False 
- True: Cho phép thêm vào tên mở rộng (.txt, .jpg) 
- False: Ngƣợc lại 
CheckFileExists Nhận một trong hai giá trị True hay False 
- True: Xuất hiện hộp cảnh báo nếu bạn nhập vào một tên 
file không tồn tại (nhập vào ô File name: trên hộp thoại 
SaveFileDialog ) 
- False: Ngƣợc lại 
CheckPathExists Nhận một trong hai giá trị True hay False 
- True: Kiểm tra đƣờng dẫn tới file có hợp lệ hay không 
trƣớc khi trả về. 
- False: Ngƣợc lại 
Filter Chọn bộ lọc cho hộp thoại (Chỉ chọn File nào). Ví dụ: 
File Text (*.txt)|*.txt| Word File (*.doc)|*.doc; 
FilterIndex Chọn số thứ tự cho bộ lọc (bộ lọc sẽ hiển thị trong mục Files 
58 
Of Types) 
FileName Set or Get tên tệp tin 
InitialDirectory Đƣờng dẫn mặc định khi hộp thoại SaveFileDialog mở ra 
RestoreDirectory Nhận một trong hai giá trị True hay False 
- True: Mở lại thƣ mục vừa mở ra lần trƣớc, với điều kiện 
thuộc tính InitialDirectory không đặt gì 
- False: Không mở lại thƣ mục vừa mở lần trƣớc 
Title Đặt tiêu đề (xuất hiện trên Titlebar) cho hộp thoại 
SaveFileDialog 
ShowHelp Cho phép xuất hiện Button Help (?) hay không? 
OverwritePrompt Xuất hiện cảnh báo nếu bạn ghi đè vào một tập tin đã tồn tại 
6.2.4. FolderBrowserDialog ( ) 
- Công dụng: Tạo ra hộp thoại Browser. 
Thuộc tính Mô tả 
RootFolder - Trả về thƣ mục gốc đƣợc chọn 
SelectedPath - Trả về thƣ mục đƣợc chọn 
* Tạo ứng dụngWindows Forms Application nhƣ hình. 
* Yêu cầu: Viết lệnh thực thi cho các Menu. 
- Nhấn vào New Mở một tệp mới 
- Nhấn vào Open: Mở một tệp đã có 
59 
- Nhấn vào Save: Lƣu tệp tin 
- Nhấn vào Font: Đặt Font chữ cho phần văn bản đƣợc chọn 
- Nhấn vào Copy: Copy đoạn văn bản đƣợc chọn 
- Nhấn vào Pase: Pase đoạn văn bản đƣợc chọn 
- Nhấn vào Close đóng ứng dụng. 
* Hƣớng dẫn: 
- Với các lệnh copy, cut, pase: gọi phƣơng thức có sẵn của RichTextBox trong sự kiện click của 
Menu tƣơng ứng. 
 Ví dụ copy: 
private void copyToolStripMenuItem_Click(object sender, EventArgs e) 
 { 
 RTBSoanThao.Copy(); 
 } 
- Với lệnh Open, sử dụng điều khiển Hộp thoại OpenFileDialog, và hiển thị lên trong sự kiện Click của 
menu tƣơng ứng. Ví dụ: 
private void openToolStripMenuItem_Click(object sender, EventArgs e) 
 { 
 openFileDialog1.Filter = "Text Format (*.txt)|*.txt|Rich Text Format (*.rtf)|*.rtf"; 
 if (openFileDialog1.ShowDialog() == DialogResult.Cancel) return; 
 RTBSoanThao.LoadFile(openFileDialog1.FileName); 
 tenfile = openFileDialog1.FileName; 
} 
60 
BÀI 7. THỰC HÀNH 3 – CÁC ĐIỀU KHIỂN WINFORM (3) 
BÀI 8. GIỚI THIỆU VỀ ADO.NET 
8.1. Giới thiệu về ADO.NET 
- ADO.NET là một trong các lớp nằm trong bộ thƣ viện lớp cơ sở của NET Framework để cho 
phép các ứng dụng Windows(nhƣ c#, VB.net) hay các ứng dụng Web(nhƣ ASP.Net) thao tác dễ 
dàng với các nguồn dữ liệu. 
- Mục tiêu chính của ADO.NET là: 
o Cung cấp các lớp để thao tác dữ liệu trong cả hai môi trƣờng là phi kết nối (Disconnected 
data) và kết nối (Connected data). 
o Tích hợp chặt chẽ với XML (Extensible Markup Language) 
o Tƣơng tác với nhiều nguồn dữ liệu thông qua mô tả chung 
o Tối ƣu truy cập nguồn dữ liệu (OLE DB & SQL server) 
o Làm việc trên môi trƣờng Internet 
- Các lớp của ADO.NET đƣợc đặt trong Namespase là System.Data 
- ADO.NET bao gồm 2 provider để thao tác với các cơ sở dữ liệu là SQL provider (nằm trong 
System.Data.SQL) dùng để truy xuất đến bất kỳ CSDL có hỗ trợ SQL; SQL Provider dữ liệu 
(nằm trong System.Data.SQLClient) chuyên dùng để truy xuất đến CSDL SQL Server (Không 
qua OLE DB nên nhanh hơn). 
- Vị trí ADO.NET trong kiến trúc của .NET Framework 
ASP.NET Windows Forms 
Drawing XML Data 
Comman language Runtime 
System Services 
ADO.NET 
Class 
Framework 
Vị trí của ADO.NET trong kiến trúc của .Net 
Framework 
61 
Từ kiến trúc ta thấy rằng ADO.NET là một phần nội tại của .NET Framework, do vậy nó có 
thể đƣợc sử dụng trong tất cả các ngôn ngữ hộ trợ .NET nhƣ C#, VB.Net mà không có sự khác biệt 
nào (Tức là các chức năng cũng nhƣ cách sử dụng hoàn toàn giống nhau). 
- ADO.NET đƣợc thiết kế để kết nối với cả dữ liệu phi kết nối trong môi trƣờng đa tầng (Multi – 
Tier). Nó sử dụng XML để trao đổi dữ liệu phi kết nối do vậy dễ dàng khi giao tiếp giữa các ứng 
dụng không phải trên nền Windows. 
- ADO.NET hỗ trợ hoàn toàn XML, nghĩa là chúng ta có thể nạp dữ liệu từ một tệp XML và thao 
tác nhƣ một CSDL, sau đó cũng có thể lƣu kết quả ngƣợc trở lại tệp XML do vậy có thể đi qua 
FireWall một cách dễ dàng. 
8.2. Các mô hình thao tác với CSDL 
Các thành phần chính của ADO.NET 
1. Connection 
2. Command 
3. Datareader 
4. DataAdapter 
5. DataSet 
Các tầng kiến trúc của ADO.NET 
Data 
DataReader 
Connction 
Command 
Connection 
Command 
DataSet 
Data Related Components 
Managed Provider Compnent 
DataStore 
DataAdapter 
62 
Các Namespace trong ADO.NET 
 System.Data.Sql: Access, SQL Server, Oracle 
 System.Data.SqlClient: SQL Server 
 System.Data.OracleClient: Oracle 
 Lƣu ý: 
 Về mặt giao tiếp lập trình ứng dụng, cả 3 thƣ viện trên không khác biệt nhau nhiều lắm. 
 Dùng thƣ viện System.Data.SqlClient sẽ truy xuất SQL Server nhanh hơn 
System.Data.Sql 
 Dùng thƣ viện System.Data.OracleClient sẽ truy xuất Oracle nhanh hơn System.Data.Sql 
8.3. Đối tƣợng Connection 
 Chức năng: Là đối tƣợng có nhiệm vụ thực hiện nhiệm vụ kết nối đến CSDL để các đối tƣợng 
nhƣ Command thao tác với CSDL thông qua Connection này. 
 Thông tin cần thiết để cung cấp cho đối tƣợng Connection là chuỗi kết nối, khai báo thông tin 
kết nối đến cơ sở dữ liệu. 
 SqlConnection sử dụng cơ chế xác thực kiểu SQL Server: 
“server=;database=;uid=;pwd=” hoặc 
 “Data Source=;Initial Catalog=;User ID=;Password=” 
 SqlConnection sử dụng cơ chế xác thực kiểu Windows: 
 “Server=;Database=;Trusted_Connection=yes” 
Ở đây,  là tên/máy chủ chứa CSDL,  là tên CSDL,  là tên đăng nhập,  là mật 
khẩu tƣơng ứng. 
Ví dụ: “server=192.168.0.1;database=qlnhanvien;uid=k28;pwd=spider” hoặc 
“Server=192.168.0.1;Database=qlnhanvien;Trusted_Connection=yes” 
 Khai báo () 
using System.Data.SqlClient; 
public partial class Form1 : Form 
 { 
 String str=@"server=192.168.0.1;database=qlnhanvien;uid=k28;pwd=spider "); 
 public SqlConnection con=new SqlConnection(st); 
 private void Form1_Load(object sender, EventArgs e) 
 { 
63 
 con.Open(); 
if (con.State.ToString() =="Open" ) 
 { 
 MessageBox.Show("Ket noi thanh cong" ); 
 } 
 } 
 } 
 Mở kết nối: Thi hành phƣng thức Open() để mở kết nối. 
con.Open(); 
 Kiểm tra kết nối: Sau khi gọi phƣơng thức Open, có thể xem đã kết nối thành công hay không 
thông qua thuộc tính State của Connection: 
if (con.State.ToString() =="Open" ) 
 Đóng kết nối: Thi hành phƣơng thức Close() để đóng kết nối 
Để tránh lỗi ta nên kiểm tra trạng thái kết nối 
private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
 { 
 if (con.State.ToString() == "Open") 
 { con.Close(); } 
 } 
64 
BÀI 9. THỰC HÀNH 4- KẾT NỐI CSDL VỚI ĐỐI TƢỢNG CONNECTION 
BÀI 10: ĐỐI TƢỢNG COMMAND, DATAREADER, PARAMETER 
10.1. Đối tƣợng Command 
 Công dụng: Dùng để thực hiện các câu lệnh SQL thao tác với CSDL nhƣ: Insert, Update, 
Select, Delete hoặc thực thi store procedure. 
- Với đối tƣợng Command chúng ta cần cung cấp chuỗi truy vấn SQL hoặc tên Store 
procedure và đối tƣợng connection đã đƣợc mở kết nối đến cơ sở dữ liệu, có thể thông qua 
phƣơng thức khởi tạo hoặc truyền vào dƣới dạng tham số. 
- Ví dụ: 
SqlCommand cm=new SqlCommand(sqlString, con); 
 Trong đó sqlString là chuỗi truy vấn sql hoặc tên store, con là đối tƣợng SqlConnection đã 
đƣợc mở kết nối 
 Có 2 cách để tạo đối tƣợng Command 
1- Tạo Command từ phƣơng thức tạo dựng 
SqlCommand dc = new SqlCommand("select * from sinhvien", con); 
2- Tạo command từ phƣơng thức CreateCommand của đối tƣợng Connection 
SqlCommand command = con.CreateCommand(); 
 command.CommandText = "select * from sinhvien"; 
3- Tạo Command bằng cách đặt các thuộc tính sau khi khai báo 
SqlCommand com = new SqlCommand(); 
 com.CommandType = CommandType.Text 
 com.CommandText ="Select * from sinhvien"; 
 com.Connection = con; 
 Nếu thực thi Store procedure thì cần phải gán giá trị cho thuộc tính CommandType nhƣ sau: 
cm.CommandType=CommandType.StoredProcedure; Mặc định giá trị thuộc tính là 
CommandType.Text để thực hiện câu lệnh Sql 
 Nếu thao tác với bảng thì cần gán giá trị cho thuộc tính Commandype là 
CommandType.TableDirect. 
 Có 4 cách để thực thi một lệnh thông qua đối tƣợng Command 
65 
 Phƣơng thức ExcuteReader: Phƣơng thức này sẽ trả về một tập các bản ghi, nó tƣơng đƣơng 
với một Recordset và thƣờng đƣợc sử dụng để thực thi các câu lệnh truy vấn nhƣ Select. Kết 
quả có thể lƣu trữ trong đối tƣợng DataReader để thao tác. 
 Cú pháp: Biến_DataReader=com.ExcuteReader(); //com biến SqlCommand. 
 Phƣơng thức ExcuteScalar(): Phƣơng thức này sẽ trả về phần tử cột đầu tiên hàng đầu tiên 
trong bảng kết quả. 
Phƣơng thức này thƣờng đƣợc sử dụng thực hiện câu lệnh truy vấn Select mà kết quả trả 
về chỉ có một hàng và một cột (Select Count(*) from sinhvien). 
 Phƣơng thức ExcuteNonQuery: Đƣợc sử dụng để thực thi các câu lệnh truy vấn hành động: 
Insert, Update, Delete 
 Phƣơng thức ExcuteXMLReader: Tạo bộ đọc từ File XML, phƣơng thức này không có trong 
oleCommand chỉ có trong sqlCommand. 
10.2. Đối tƣợng DataReader 
Công dụng: Dùng để đón nhận kết quả trả về từ đối tƣợng Command. Dữ liệu là chỉ đọc 
theo chiều tiến (Readoly). 
 Khai báo và lấy dữ liệu từ Command. Đối tƣợng DataReader không có phƣơng thức khởi tạo 
private void button1_Click(object sender, EventArgs e) 
 { 
 StringBuilder st = new StringBuilder(); 
 dc = new SqlCommand("select * from sinhvien", con); 
 SqlReader dr ; // Khai báo DataReader 
 dr = dc.ExecuteReader(); // Lấy dữ liệu từ Command 
 while (dr.Read() == true) // Duyệt qua các bản ghi 
 { 
 st.AppendLine(dr.GetValue(2).ToString() ); 
 } 
 MessageBox.Show(st.ToString()); 
 dr.Close(); 
 dc.Dispose(); 
66 
 } 
10.3. Đối tƣợng Parameter 
Sử dụng đối tợng Parameter để tạo ra các tham số và truyền vào giá trị cho các tham 
số trong thủ tục Store procedure của đối tƣợng SqlCommand, hoặc các tham số trong báo 
biểu. 
Ví dụ 1: Sử dụng đối tƣợng Parameter để tạo và truyền giá trị cho các đối số của 
StoreProcedure 
private void CmdStoredProc_Click(object sender, EventArgs e) 
 { 
 dc = new SqlCommand(); 
 dc.Connection = con; 
 dc.CommandType = CommandType.StoredProcedure; 
 dc.CommandText = "NhapSinhVien"; 
// Thủ tục lƣu trữ nội 
// Tạo đối tƣợng Parameter để tạo ra các tham số và truyền vào // giá trị cho các 
tham số trong thủ tục lƣu trữ nội 
// NhapSinhVien 
//b1. Tạo đối tƣợng Parameter gồm có: Tên param, kiểu dữ liệu, độ rộng 
 SQLParameter p= new SqlParameter("@malop", SqlType.VarChar, 20); 
//b2. Gán giá trị 
 p.Value = "01.1"; 
//b3. Thêm đối tƣợng param vào danh sách các param của đối tƣợng command 
67 
 dc.Parameters.Add(p); 
 p = new SqlParameter("@MaSv", SqlType.VarChar, 20); 
 p.Value = "01.1.190"; 
 dc.Parameters.Add(p); 
 p = new SqlParameter("@TenSV", SqlType.VarChar); 
 p.Value = "Chu van quenh"; 
 dc.Parameters.Add(p); 
b4. gọi phƣơng thức Excute để thi hành. 
 dc.ExecuteNonQuery(); 
 } 
Ví dụ 2: Sử dụng đối tƣợng Parameter duyệt qua các đối số của StoreProcedure 
đƣợc lấy về trong đối tƣợng Command. 
public void GoiSProcedure(string Sprocedure_name, params Object[] gt) 
 { 
 SqlCommand dc = new SqlCommand(); 
 dc.CommandType = CommandType.StoredProcedure; 
 dc.CommandText = Sprocedure_name; 
 if (con.State.ToString() == "Closed") 
 con.Open(); 
68 
 dc.Connection = con; 
// Sử dụng phƣơng thức tĩnh DeriveParameters của lớp SqlCommandBuilder //để 
lấy về các đối số cho đối tƣơng Command. 
 SqlCommandBuilder.DeriveParameters(dc); 
 for (int i = 1; i < dc.Parameters.Count;i++ ) 
 { 
 dc.Parameters[i].Value = gt[i-1]; 
 } 
 dc.ExecuteNonQuery(); 
 con.Close(); 
 dc.Dispose(); 
 } 
10.4. Các thao tác thêm, sửa, xóa dữ liệu theo mô hình hƣớng kết nối. 
Các thao tác trên cơ sở dữ liệu có thể là: Insert, Update, Delete, Select 
b1. Cần khai báo một biến đối tƣợng SqlConnection, và mở kết nối đến cơ sở dữ liệu. 
b2. Khi cần thực hiện các câu lệnh truy vấn thì tạo một biến SqlCommand gắn với biến 
SqlConnection đã mở. 
b3. Gán giá trị cho thuộc tính CommandType của biến đối tƣợng SqlCommand 
b4. Gán câu lệnh truy vấn (select, insert, update, delete, gọi store procedure) cho thuộc tính 
CommandText của biến đối tƣợng SqlCommand 
b5. Thi hành phƣơng thức ExcuteNonquery() của biến đối tƣợng SqlCommand với các cấu lệnh truy 
vấn (Insert, Update, Delecte) và ExcuteReader với câu lệnh Select 
b6. Đóng và giải phóng các biến đối tƣợng nếu không cần thiết. 
69 
Ví dụ 1: Insert 
private void cmdcapnhat_Click(object sender, EventArgs e) 
 { 
 dc = new SqlCommand(); // b2. 
 dc.Connection = con; 
 // b3. có thể b3 không cần thiết nếu gt là CommandType.Text; 
 dc.CommandType = CommandType.Text; // Giá trị này là gt mặc định 
 // b4. 
 dc.CommandText = "Insert into sinhvien values('" + this.Txtmalop.Text + "','" + 
this.TxtmaSV.Text + "','" + this.txtTen.Text + "')"; 
 dc.ExecuteNonQuery(); // b5. 
 dc.Dispose(); // b6. 
 } 
Ví dụ 2: Update 
private void cmdupdate_Click(object sender, EventArgs e) 
 { 
 dc = new SqlCommand("select * from sinhvien", con); 
 dc.CommandText = "Update sinhvien set malop='" + this.Txtmalop.Text + "',masvien='" + 
this.TxtmaSV.Text + "', tensvien='" + this.txtTen.Text + "' where masvien='" + this.TxtmaSV.Text + 
"'" ; 
 dc.ExecuteNonQuery(); 
 dc.Dispose(); 
 } 
Ví dụ 3: Delete 
private void cmddel_Click(object sender, EventArgs e) 
70 
 { 
 dc = new SqlCommand("select * from sinhvien", con); 
 dc.CommandText = "delete from sinhvien where masvien='" + this.TxtmaSV.Text + "'"; 
 dc.ExecuteNonQuery(); 
 dc.Dispose(); 
 } 
 Bài tập ví dụ 
Giả sử ta đã có cơ sở dữ liệu quanlythuvien trong SQL Server có quan hệ nhƣ sau: 
Thiết kế Form để tạo mới 1 tài khoản nhƣ sau 
71 
Y1: Xây dựng lớp thao tác với cơ sở dữ liệu thực hiện các yêu cầu sau: 
- Phƣơng thức khởi tạo để truyền vào thông tin kết nối 
- Phƣơng thức Open để kết nối đến CSDL 
- Phƣơng thức Close để đóng kết nối đến CSDL 
- Phƣơng thức ExcuteReader() để thực thi câu lệnh truy vấn Select 
- Phƣơng thức ExcuteNonQuery() để thực thi câu lệnh truy vấn hành động. 
Y2: Viết chƣơng trình sử dụng lớp xây dựng ở trên thực hiện các yêu cầu sau: 
- Khi form Load, hiển thị thông tin của nhân viên lên DataGridView 
72 
- Khi ngƣời sử dụng nhập thông tin vào các điều khiển, nhấn vào button TaoMoi, 
thêm mới nhân viên vào trong CSDL đồng thời hiển thị lên DataGridView 
- Khi ngƣời sử dụng chọn một nhân viên trên DataGridView, hiển thị thông tin nhân 
viên đó xuống các điều khiển tƣơng ứng 
- Khi ngƣời sử dụng nhấn vào button Xoa, xóa thông tin của nhân viên có mã nhân 
viên bằng mã nhân viên trong điều khiển txtMaNV trên cơ sở dữ liệu, đồng thời xóa 
thông tin trên DataGridView 
- Khi ngƣời sử dụng nhấn vào button Sửa, sửa thông tin của nhân viên có mã nhân 
viên bằng mã nhân viên trong điều khiển txtMaNV và các thông tin mới là các 
thông tin trên các điều khiển tƣơng ứng. 
Hƣớng dẫn: 
- Xây dựng lớp clsDuLieu 
class clsCSDL 
 { 
 string st = ""; 
//@"server=HUE\MINHHUE; database=QLTV; Integrated security=true" 
 SqlConnection con; 
 /// 
 /// kết nối đến cơ sở dữ liệu với quyền Window 
 /// 
 /// Thông tin severName 
 /// Thông tin về DataName 
 public clsCSDL(string SV, string DN) 
 { 
 st = @"server=" + SV + "; database=" + DN + "; Integrated security=true"; 
 con = new SqlConnection(st); 
 } 
 public clsCSDL(string SV, string DN, String UN, string PW) 
 { 
 st = @"server=" + SV + "; database=" + DN + "; UId=" + UN + "; Pwd=" + PW; 
 con = new SqlConnection(st); 
 } 
 public void MoKetKetNoi() 
73 
 { 
 if (con.State==ConnectionState.Closed) 
 con.Open(); 
 } 
 public void DongKetNoi() 
 { 
 if (con.State != ConnectionState.Closed) 
 { 
 con.Close(); 
 } 
 } 
 /// 
 /// Thực thi câu lệnh truy vấn hành động SQL (Insert, Update, Delete) 
 /// 
 /// 
 public void ExcuteNonQuery(string sqlstring) 
 { 
 /* chú ý trong mô hình hƣớng kết nối thì đối tƣợng SqlConnection bắt buộc phải đƣợc 
mở 
 vì vậy việc gọi phƣơng thức MoKetNoi() là bắt buộc 
 */ 
 MoKetKetNoi(); 
 SqlCommand cm = new SqlCommand(sqlstring, con); 
 cm.ExecuteNonQuery(); 
 } 
 /// 
 /// Thực thi câu lệnh truy vấn SQL Select 
 /// 
 /// 
 /// 
 public SqlDataReader ExcuteReader(string sqlstring) 
 { 
 MoKetKetNoi(); 
 SqlCommand cm = new SqlCommand(sqlstring, con); 
 SqlDataReader drr = cm.ExecuteReader(); 
 return drr; 
 } 
} 
Trên Form, khai báo và sử dụng lớp clsCSDL và gọi các phƣơng thức thực hiện với 
CSDL cần thiết tƣơng ứng. 
- Ví dụ với yêu cầu: Khi form Load, hiển thị thông tin của nhân viên lên 
DataGridView. 
74 
public partial class frmQLNVien : Form 
 { 
 clsCSDL dl = new clsCSDL(@"HUE\MINHHUE", "QLTV"); 
 public frmQLNVien() 
 { 
 InitializeComponent(); 
 } 
 private void frmQLHangHoa_Load(object sender, EventArgs e) 
 { 
// Thêm các cột có cấu trúc giống bảng vào DataGridView 
 dataGridView1.Columns.Add("MaNV", "Mã Nhân viên"); 
 dataGridView1.Columns.Add("tenNV", "Tên Nhân viên"); 
 dataGridView1.Columns.Add("DiaChi", "Địa chỉ"); 
 dataGridView1.Columns.Add("TenDN", "Tên đăng nhập"); 
 dataGridView1.Columns.Add("QuyenHan", "Quyền hạn"); 
// Gọi phƣơng thức đã xây dựng của đối tƣợng lớp clsCSDL 
 SqlDataReader dr=dl.ExcuteReader("Select * from NhanVien"); 
 while (dr.Read() ) // Đọc dữ liệu từ DataReader đƣa lên DataGridView 
 { 
 dataGridView1.Rows.Add(dr[0], dr[1], dr[2], dr[3], dr[4], dr[5]); 
 } 
 } 
-Ví dụ với yêu cầu Button Xóa 
 private void butXoa_Click(object sender, EventArgs e) 
 { 
 // Viết câu lệnh truy vấn Delete 
 string st = "Delete * from NhanVien where maNV='" + txtMa.Text + "'"; 
 //Gọi phƣơng thức thực thi câu lệnh truy vấn hành động của đối tƣợng lớp clsCSDL 
 dl.ExcuteNonQuery(st); 
 // Tìm dòng trên DataGridView và xóa 
 for (int i = 0; i < dataGridView1.Rows.Count; i++) 
 { 
 if (dataGridView1.Rows[i].Cells[0].Value.ToString() == txtMa.Text) 
 { 
 dataGridView1.Rows.RemoveAt(i); 
 break; 
 } 
 } 
 } 
75 
BÀI 11. THỰC HÀNH 5 – THAO TÁC CSDL THEO MÔ HÌNH HƢỚNG KẾT 
NỐI 
BÀI 12. ĐỐI TƢỢNG DATA ADAPER VÀ DATASET 
12.1. Đối tƣợng DataAdaper 
 Công dụng: Có chức năng nhƣ một cầu nối giữa nguồn (tệp) dữ liệu và các bảng đƣợc cached 
trong bộ nhớ (đối tƣợng DataSet). DataAdapter điền dữ liệu vào một DataSet hay DataTable từ 
một nguồn dữ liệu sử dụng phƣơng thức Fill(). Còn khi cập nhật dữ liệu ngƣợc trở lại nguồn dữ 
liệu thì sử dụng phƣơng thức Update() của đối tƣợng DataAdapter. 
Tạo một DataAdapter ta có thể tạo từ một đối tƣợng connection đang mở hoặc từ một chuỗi 
kết nối (connection chƣa đƣợc mở). 
- Ví dụ phƣơng thức Fill dữ liệu vào Datatable 
 SqlAdapter DA = new SqlAdapter(strSQL, ChuoiKetNoi); 
 DataTable dt = new DataTable(); 
 DA.Fill(dt); 
 return dt; 
- Ví dụ cập nhật dữ liệu từ DataTable lên cơ sở dữ liệu thông qua đối tƣợng DataAdapter 
// Trong đó dt là đối tƣợng DataTable chứa thông tin của Sinh viên đƣợc thay đổi. 
 SqlAdapter da = new SqlAdapter("Select * from SinhVien" , ChuoiKetNoi); 
 SqlCommandBuilder cb = new SqlCommandBuilder(da); 
 da.Update(dt); 
12.2. Đối tƣợng DataSet. 
DataSet đóng vai trò của một CSDL in-memory (CSDL nằm trong bộ nhớ). Thuộc tính Tables 
của DataSet là một tập hợp các DataTable chứa dữ liệu và lƣợc đồ dữ liệu (data schema) mô tả dữ liệu 
trong DataTable. Thuộc tính Relations chứa tập hợp các đối tƣợng DataRelation xác định cách thức liên 
kết các đối tƣợng DataTable của DataSet. Lớp DataSet cũng hỗ trợ việc sao chép, trộn, và xóa DataSet 
thông qua các phƣơng thức tƣơng ứng là Copy, Merge, và Clear. 
DataSet và DataTable là phần lõi của ADO.NET và chúng không là đặc trƣng của một data 
provider nào (giống nhƣ ở các lớp Connection, DataReader, DataAdapter). Một ứng dụng có thể định 
nghĩa và nạp dữ liệu từ nguồn bất kỳ (chứ không nhất thiết là từ một CSDL) vào DataSet. 
Bên cạnh các DataTable và các DataRelation, một DataSet còn có thể chứa các thông tin tùy biến 
khác đƣợc định nghĩa bởi ứng dụng. Hình dƣới đây mô tả cả lớp chính trong DataSet. Trong số các thuộc 
tính này, chú ý thuộc tính PropertyCollection; đó là các thuộc tính đƣợc lƣu trữ dƣới dạng một hash table 
(bảng băm), thƣờng chứa một giá trị time stamp hay các thông tin đặc tả nhƣ các yêu cầu hợp lệ hóa 
(validation requirements) cho column trong các DataTable trong DataSet. 
76 
1- DataTable 
Thuộc tính DataSet.Tables chứa các đối tƣợng DataTable. Mỗi đối tƣợng trong tập hợp này có thể 
đƣợc truy xuất bằng chỉ số hoặc bằng tên. 
Các DataTable trong tập hợp DataSet.DataTables mô phỏng các Table trong CSDL quan hệ (các 
row, column, ). Các thuộc tính quan trọng nhất của lớp DataTable là Columns và Rows định nghĩa cấu 
trúc và nội dung bảng dữ liệu. 
2- DataColumn 
Thuộc tính DataTable.Columns chứa một tập các đối tƣợng DataColumn biểu diễn các trƣờng dữ 
liệu trong DataTable. Bảng dƣới đây tóm tắt các thuộc tính quan trọng của lớp DataColumn. 
Phƣơng thức Mô tả 
ColumnName Tên column 
DataType Kiểu của dữ liệu chứa trong column này 
Ví dụ: col1.DataType = System.Type.GetType("System.String") 
MaxLength Độ dài tối đa của một text column. -1 nếu không xác định độ dài tối đa 
ReadOnly Cho biết giá trị của column có đƣợc chỉnh sửa hay không 
AllowDBNull Giá trị Boolean cho biết column này có đƣợc chứa giá trị NULL hay không 
Unique Giá trị Boolean cho biết column này có đƣợc chứa các giá trị trùng nhau hay 
không 
Expression Biểu thức định nghĩa cách tính giá trị của một column 
Ví dụ: colTax.Expression = "colSales * .085"; 
Caption Tiêu đề hiển thị trong thành phần điều khiển giao diện đồ họa 
DataTable Tên của đối tƣợng DataTable chứa column này 
77 
Các column của DataTable đƣợc tạo ra một cách tự động khi table đƣợc nạp dữ liệu từ kết quả 
của một database query hoặc từ kết quả đọc đƣợc ở một file XML. Tuy nhiên, chúng ta cũng có thể viết 
code để tạo động các column. Đoạn code dƣới đây sẽ tạo ra một đối tƣợng DataTable, sau đó tạo thêm 
các đối tƣợng DataColumn, gán giá trị cho các thuộc tính của column, và bổ sung các DataColumn này 
vào DataTable. 
DataTable tb = new DataTable("DonHang"); 
DataColumn dCol = new DataColumn("MaSo", Type.GetType("System.Int16")); 
dCol.Unique = true; // Dữ liệu của các dòng ở column này không đƣợc trùng nhau 
dCol.AllowDBNull = false; 
tb.Columns.Add(dCol); 
dCol = new DataColumn("DonGia", Type.GetType("System.Decimal")); 
tb.Columns.Add(dCol); 
dCol = new DataColumn("SoLuong",Type.GetType("System.Int16")); 
tb.Columns.Add(dCol); 
dCol= new DataColumn("ThanhTien",Type.GetType("System.Decimal")); 
dCol.Expression= "SoLuong*DonGia"; 
tb.Columns.Add(dCol); 
// Liệt kê danh sách các Column trong DataTable 
foreach (DataColumn dc in tb.Columns) 
{ 
 Console.WriteLine(dc.ColumnName); 
 Console.WriteLine(dc.DataType.ToString()); 
} 
Để ý rằng column MaSo đƣợc định nghĩa để chứa các giá trị duy nhất. Ràng buộc này giúp cho 
column này có thể đƣợc dùng nhƣ là trƣờng khóa để thiết lập relationship kiểu parent-child với một bảng 
khác trong DataSet. Để mô tả, khóa phải là duy nhất – nhƣ trong trƣờng hợp này – hoặc đƣợc định nghĩa 
nhƣ là một primary key của bảng. Ví dụ dƣới đây mô tả cách xác định primary key của bảng: 
DataColumn[] col = {tb.Columns["MaSo"]}; 
tb.PrimaryKey = col; 
Nếu một primary key chứa nhiều hơn 1 column – chẳng hạn nhƣ HoDem và Ten – bạn có thể tạo 
ra một ràng buộc unique constraint trên các nhƣ ví dụ dƣới đây: 
DataColumn[] cols = {tb.Columns["HoDem"], tb.Columns["Ten"]}; 
tb.Constraints.Add(new UniqueConstraint("keyHoVaTen", cols)); 
Chúng ta sẽ xem xét cách thức tạo relationship cho các bảng và trộn dữ liệu ở phần tiếp theo. 
78 
3- DataRows 
Dữ liệu đƣợc đƣa vào table bằng cách tạo mới một đối tƣợng DataRow, gán giá trị cho các 
column của nó, sau đó bổ sung đối tƣợng DataRow này vào tập hợp Rows gồm các DataRow của table. 
DataRow row; 
row = tb.NewRow(); // Tạo mới DataRow 
row["DonGia"] = 22.95; 
row["SoLuong"] = 2; 
row["MaSo"] = 12001; 
tb.Rows.Add(row); // Bổ sung row vào tập Rows 
Console.WriteLine(tb.Rows[0]["ThanhTien"].ToString()); // 45.90 
Một DataTable có các phƣơng thức cho phép nó có thể commit hay roll back các thay đổi đƣợc 
tạo ra đối với table tƣơng ứng. Để thực hiện đƣợc điều này, nó phải nắm giữ trạng thái của mỗi dòng dữ 
liệu bằng thuộc tính DataRow.RowState. Thuộc tính này đƣợc thiết lập bằng một trong 5 giá trị kiểu 
enumeration DataRowState sau: Added, Deleted, Detached, Modifed, hoặc Unchanged. Xem xét ví dụ 
sau: 
tb.Rows.Add(row); // Added 
tb.AcceptChanges(); // ...Commit changes 
Console.Write(row.RowState); // Unchanged 
tb.Rows[0].Delete(); // Deleted 
// Undo deletion 
tb.RejectChanges(); // ...Roll back 
Console.Write(tb.Rows[0].RowState); // Unchanged 
DataRow myRow; 
MyRow = tb.NewRow(); // Detached 
Hai phƣơng thức AcceptChanges và RejectChanges của DataTable là tƣơng đƣơng với các thao 
tác commit và rollback trong một CSDL. Các phƣơng thức này sẽ cập nhất mọi thay đổi xảy ra kể từ khi 
table đƣợc nạp, hoặc từ khi phƣơng thức AcceptChanges đƣợc triệu gọi trƣớc đó. Ở ví dụ trên, chúng ta 
có thể khôi phục lại dòng bị xóa do thao tác xóa là chƣa đƣợc commit trƣớc khi phƣơng thức 
RejectChanges đƣợc gọi. Điều đáng lƣu ý nhất đó là, những thay đổi đƣợc thực hiện là ở trên table chứ 
không phải là ở data source. 
ADO.NET quản lý 2 giá trị - ứng với 2 phiên bản hiện tại và nguyên gốc - cho mỗi column trong 
một dòng dữ liệu. Khi phƣơng thức RejectChanges đƣợc gọi, các giá trị hiện tại sẽ đƣợc đặt khôi phục lại 
79 
từ giá trị nguyên gốc. Điều ngƣợc lại đƣợc thực hiện khi gọi phƣơng thức AcceptChanges. Hai tập giá trị 
này có thể đƣợc truy xuất đồng thời thông qua các giá trị liệt kê DataRowVersion là: Current và Original: 
DataRow r = tb.Rows[0]; 
r["DonGia"]= 14.95; 
r.AcceptChanges(); 
r["DonGia"]= 16.95; 
Console.WriteLine("Current: {0} Original: {1} ", 
 r["Price", DataRowVersion.Current], 
 r["Price", DataRowVersion.Original]); 
Kết quả in ra: 
Current: 16.95 Original: 14.95 
12.3. Nạp dữ liệu vào DataSet 
Chúng ta đã biết cách thành lập một DataTable và xử lý dữ liệu theo kiểu từng dòng một. Phần 
này sẽ trình bày phƣơng pháp để dữ liệu và lƣợc đồ dữ liệu đƣợc nạp tự động từ CSDL quan hệ vào các 
table trong DataSet. 
a. Dùng DataReader để nạp dữ liệu vào DataSet 
Đối tƣợng DataReader có thể đƣợc sử dụng để liên hợp đối tƣợng DataSet hay DataTable trong 
việc nạp các dòng dữ liệu kết quả (của query trong DataReader). 
cmd.CommandText = "SELECT * FROM nhanvien"; 
SQlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
DataTable dt = new DataTable("nhanvien"); 
dt.Load(rdr); // Nạp dữ liệu và lƣợc đồ vào table 
Console.WriteLine(rdr.IsClosed); // True 
Đối tƣợng DataReader đƣợc tự động đóng sau khi tất cả các dòng dữ liệu đƣợc nạp vào table. Do 
đã sử dụng tham số CommandBehavior.CloseConnection trong phƣơng thức ExecuteReader nên 
connection đƣợc đóng sau khi DataReader đƣợc đóng. 
Nếu table đã có dữ liệu, phƣơng thức Load sẽ trộn dữ liệu mới với các dòng dữ liệu đang có trong 
nó. Việc trộn này xảy ra chỉ khi các dòng dữ liệu có chung primary key. Nếu không có primary key đƣợc 
định nghĩa, các dòng dữ liệu sẽ đƣợc nối vào sau tập dữ liệu hiện tại. Chúng ta có thể sử dụng phƣơng 
thức nạp chồng khác của phƣơng thức Load để quy định cách thức làm việc. Phƣơng thức Load với tham 
số kiểu enumeration LoadOption gồm 1 trong 3 giá trị OverwriteRow, PreserveCurrentValues, hoặc 
UpdateCurrentValues tƣơng ứng với tùy chọn ghi đè nguyên dòng, giữ lại các giá trị hiện tại, hoặc cập 
80 
nhật các giá trị hiện tại. Đoạn code dƣới đây minh họa cách trộn dữ liệu vào các dòng hiện tại theo kiểu 
ghi đè các giá trị hiện tại: 
cmd.CommandText = "SELECT * FROM nhanvien WHERE diachi=’a’"; 
DBDataReader rdr = cmd.ExecuteReader(); 
DataTable dt = new DataTable("nhanvien"); 
dt.Load(rdr); 
Console.Write(dt.Rows[0]["HoTen"]); // giả sử giá trị nhận đƣợc là “tnv spider” 
// Gán khóa chính 
DataColumn[] col = new DataColumn[1]; 
col[0] = dt.Columns["Manv"]; 
dt.PrimaryKey = col; 
DataRow r = dt.Rows[0]; // lấy dòng đầu tiên 
r["HoTen"] = "ten moi"; // thay đổi giá trị của cột HoTen 
// Do reader đã bị đóng sau khi nạp vào data table nên phải giờ phải fill lại 
rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
// Trộn dữ liệu với các dòng hiện tại. Ghi đè các giá trị hiện tại 
dt.Load(rdr, LoadOption.UpdateCurrentValues); 
// Giá trị cập nhật đã bị ghi đè!!! 
Console.Write(dt.Rows[0]["HoTen"]); // “tnv spider” 
b. Nạp dữ liệu vào DataSet bằng DataAdapter 
Đối tƣợng DataAdapter có thể đƣợc dùng để nạp một table hiện có vào một table khác, hoặc tạo 
mới và nạp dữ liệu cho table từ kết quả của một query. Bƣớc đầu tiên là tạo ra một đối tƣợng 
DataAdapter tƣơng ứng với data provider cụ thể. Dƣới đây là các ví dụ để tạo ra đối tƣợng DataAdapter: 
(1) Tạo từ Connection string và câu truy vấn SELECT: 
String sql = "SELECT * FROM nhanvien"; 
SqlAdapter da = new SqlAdapter(sql, connStr); 
(2) Tạo từ đối tƣợng Connection và câu truy vấn SELECT: 
SqlConnection conn = new SqlConnection(connStr); 
SqlAdapter da = new SqlAdapter(sql, conn); 
(3) Gán đối tƣợng Command cho thuộc tính SelectCommand 
81 
SqlAdapter da = new SqlAdapter(); 
SqlConnection conn = new SqlConnection(connStr); 
da.SelectCommand = new SqlCommand(sql, conn); 
Sau khi đối tƣợng DataAdapter đã đƣợc tạo ra, phƣơng thức Fill của nó đƣợc thực thi để nạp dữ 
liệu vào table (đang tồn tại hoặc tạo mới). Ở ví dụ dƣới đây, một table mới đƣợc tạo ra với tên mặc định 
là “Table”: 
DataSet ds = new DataSet(); 
// Tạo ra một DataTable, nạp dữ liệu vào DataTable, và đƣa DataTable vào DataSet 
int nRecs = da.Fill(ds); // trả về số lƣợng record đƣợc nạp vào DataTable 
// Nếu muốn đặt tên cho DataTable trong DataSet thay vì lấy tên mặc định 
// thì sử dụng code nhƣ thế này 
int nRecs = da.Fill(ds, "nhanvien ") 
Với một table đang tồn tại, tác dụng của lệnh Fill tùy thuộc vào table có primary hay không. Nếu 
có, những dòng dữ liệu có khóa trùng với dòng dữ liệu mới sẽ đƣợc thay thế. Các dòng dữ liệu mới 
không trùng với dữ liệu hiện có sẽ đƣợc nối vào sau DataTable. 
12.4. Cập nhật CSDL bằng DataAdapter 
Sau khi DataAdapter đã nạp dữ liệu vào table, connection sẽ đƣợc đóng, và các thay đổi sau đó 
đối sau đó tạo ra cho dữ liệu sẽ chỉ có ảnh hƣởng trong DataSet chứ không phải là ở dữ liệu nguồn! Để 
thực sự cập nhật các thay đổi này lên nguồn dữ liệu, DataAdapter phải đƣợc sử dụng để khôi phục 
connection và gửi các dòng dữ liệu đã đƣợc thay đổi lên CSDL. 
Ngoài SelectCommand, DataAdapter có thêm 3 thuộc tính Command nữa, gồm InsertCommand, 
DeleteCommand và UpdateCommand, làm nhiệm vụ thực hiện các thao tác tƣơng ứng với tên thuộc tính 
của chúng (chèn, xóa, cập nhật). Các Command này đƣợc thực thi khi phƣơng thức Update của 
DataAdapter đƣợc triệu gọi. Khó khăn nằm ở chỗ tạo ra các query command phức tạp này (cú pháp của 
câu lệnh SQL tƣơng ứng càng dài dòng và phức tạp khi số lƣợng column nhiều lên). Rất may là các data 
provider đều có cài đặt một lớp gọi là CommandBuilder dùng để quản lý việc tạo các Command nói trên 
một cách tự động. 
a. CommandBuilder 
Một đối tƣợng CommandBuilder sẽ sinh ra các Command cần thiết để thực hiện việc cập nhật 
nguồn dữ liệu tạo ra bởi DataSet. Cách tạo đối tƣợng CommandBuilder là truyền đối tƣợng DataAdapter 
cho phƣơng thức khởi dựng của nó; sau đó, khi phƣơng thức DataAdapter.Update đƣợc gọi, các lệnh 
SQL sẽ đƣợc sinh ra và thực thi. Đoạn code dƣới đây minh họa cách thức thay đổi dữ liệu ở một 
DataTable và cập nhật lên CSDL tƣơng ứng bằng DataAdapter: 
//Giả sử đã có 1 DataSet ds chứa dữ liệu của bảng khoa 
82 
DataTable dt= ds.Tables["khoa"]; 
// (1) Dùng commandBuilder để sinh ra các Command cần thiết để update 
SqlCommandBuilder sb = new SqlCommandBuilder(da); 
// (2) Thực hiện thay đổi dữ liệu: thêm 1 khoa mới 
DataRow drow = dt.NewRow(); 
drow["Makhoa"] = 12; 
drow["tenkhoa"] = "abc"; 
dt.Rows.Add(drow); 
// (3) Thực hiện thay đổi dữ liệu: xóa 1 khoa 
dt.Rows[4].Delete(); 
//(4) Thực hiện thay đổi dữ liệu: thay đổi giá trị 1 dòng dữ liệu 
dt.Rows[5]["tenkhoa"] = "this must be changed"; 
//(5) Tiến hành cập nhật lên CSDL 
int nUpdate = da.Update(ds, "khoa"); 
MessageBox.Show("Số dòng đƣợc thay đổi: " + nUpdate.ToString()); //  3 
Có một số hạn chế khi sử dụng CommandBuilder: Command Select ứng với DataAdapter chỉ 
đƣợc tham chiếu đến 1 table, và table nguồn trong CSDL phải bao gồm một primary key hoặc một 
column chứa các giá trị duy nhất. Column này (hay tổ hợp các columns) phải đƣợc bao gồm trong Đƣa 
dữ liệu lên các điều khiển 
12.5. Các thao tác với CSDL theo mô hình phi kết 
Ví dụ thiết kế Form nhƣ sau: 
Giả sử ta đã có cơ sở dữ liệu quanlythuvien trong SQL Server có quan hệ nhƣ sau: 
83 
Thiết kế Form để tạo mới 1 tài khoản nhƣ sau 
Y1: Xây dựng lớp thao tác với cơ sở dữ liệu thực hiện các yêu cầu sau: 
84 
- Phƣơng thức khởi tạo để truyền vào thông tin kết nối 
- Phƣơng thức FillData() để thực lấy dữ liệu từ CSDL đƣa vào đối tƣợng DataTable 
- Phƣơng thức InsertRowTable() thêm một bản ghi vào đối tƣợng DataTable 
- Phƣơng thức UpdateRowTable() sửa một bản ghi trong đối tƣợng DataTable 
- Phƣơng thức DeleteRowTable() xóa một bản ghi trong đối tƣợng DataTable 
Y2: Viết chƣơng trình sử dụng lớp xây dựng ở trên thực hiện các yêu cầu sau: 
- Khi form Load, hiển thị thông tin của nhân viên lên DataGridView 
- Khi ngƣời sử dụng nhập thông tin vào các điều khiển, nhấn vào button TaoMoi, 
thêm mới nhân viên vào trong CSDL đồng thời hiển thị lên DataGridView 
- Khi ngƣời sử dụng chọn một nhân viên trên DataGridView, hiển thị thông tin nhân 
viên đó xuống các điều khiển tƣơng ứng 
- Khi ngƣời sử dụng nhấn vào button Xoa, xóa thông tin của nhân viên có mã nhân 
viên bằng mã nhân viên trong điều khiển txtMaNV trên cơ sở dữ liệu, đồng thời xóa 
thông tin trên DataGridView 
- Khi ngƣời sử dụng nhấn vào button Sửa, sửa thông tin của nhân viên có mã nhân 
viên bằng mã nhân viên trong điều khiển txtMaNV và các thông tin mới là các 
thông tin trên các điều khiển tƣơng ứng. 
Hƣớng dẫn: 
- Xây dựng lớp clsCSDL nhƣ sau: 
class clsCSDL 
 { 
 string st = ""; 
//@"server=HUE\MINHHUE; database=QLTV; Integrated security=true" 
 SqlConnection con; 
 /// 
 /// kết nối đến cơ sở dữ liệu với quyền Window 
 /// 
85 
 /// Thông tin severName 
 /// Thông tin về DataName 
 public clsCSDL(string SV, string DN) 
 { 
 st = @"server=" + SV + "; database=" + DN + "; Integrated security=true"; 
 con = new SqlConnection(st); 
 } 
 public clsCSDL(string SV, string DN, String UN, string PW) 
 { 
 st = @"server=" + SV + "; database=" + DN + "; UId=" + UN + "; Pwd=" + PW; 
 con = new SqlConnection(st); 
 } 
 /// 
 /// Lấy dữ liệu từ cơ sở dữ liệu và fill vào bảng 
 /// 
 /// Câu lệnh select 
 /// Bảng mà đã fill dữ liệu vào 
 public DataTable FillDataTable(string sqlSelect) 
 { 
 DataTable dt = new DataTable(); 
 SqlDataAdapter da = new SqlDataAdapter(sqlSelect, con); 
 da.Fill(dt); 
 return dt; 
 } 
 /// 
 /// Thêm một dòng vào DataTable 
 /// 
 /// Tên bảng trong DataSet 
 /// Giá trị của các trƣờng 
 /// Đối tƣợng DataTable tham chiếu đến bảng vừa đƣợc thêm 
 /// 
 public void InsertData(DataTable dt, params object[] Value) 
 { 
 // Tạo ra một dòng có cấu trúc giống bảng 
 DataRow dr = dt.NewRow(); 
 // Gan gia tri cho tung truong 
 for (int i = 0; i < Value.Length; i++) 
 { 
 dr[i] = Value[i]; // Gán giá trị cho các trƣờng 
 } //them dong vao bang 
 dt.Rows.Add(dr); 
 } 
 /// 
 /// Sửa thông tin một dòng trong Datatable 
 /// 
 /// DataTable cần sử 
 /// Tập hợp các giá trị mới 
86 
 public v
            Các file đính kèm theo tài liệu này:
 01200005_1469_1983549.pdf 01200005_1469_1983549.pdf