Tải bản đầy đủ (.pdf) (123 trang)

Giáo trình môn Xây dựng ứng dụng windows

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (3.03 MB, 123 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

<b>ỦY BAN NHÂN DÂN THÀNH PHỐ HỒ CHÍ MINH </b>
<b>TRƯỜNG CAO ĐẲNG KINH TẾ KỸ THUẬT </b>


<b>THÀNH PHỐ HỒ CHÍ MINH </b>
<b> </b>


<b> </b>
<b> </b>
<b> </b>


<b>GIÁO TRÌNH </b>



<b>MƠ ĐUN /MƠN HỌC : </b>

<b>XÂY DỰNG ỨNG DỤNG WINDOWS </b>



<b>NGHỀ: HỆ THỐNG THƠNG TIN </b>


<b>TRÌNH ĐỘ: CAO ĐẲNG </b>



<b> </b>









</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

<b>ỦY BAN NHÂN DÂN THÀNH PHỐ HỒ CHÍ MINH </b>
<b>TRƯỜNG CAO ĐẲNG KINH TẾ KỸ THUẬT </b>


<b>THÀNH PHỐ HỒ CHÍ MINH </b>

<b> </b>


<b> </b>
<b> </b>
<b> </b>
<b>GIÁO TRÌNH </b>


<b>MƠ ĐUN /MƠN HỌC: XÂY DỰNG ỨNG DỤNG WINDOWS </b>
<b>NGHỀ: HỆ THỐNG THƠNG TIN </b>


<b>TRÌNH ĐỘ: CAO ĐẲNG </b>
<b> </b>




<b> THÔNG TIN CHỦ NHIỆM ĐỀ TÀI </b>
Họ tên: Huỳnh Khắc Duy


Học vị: Thạc sỹ


Đơn vị: Khoa Công Nghệ Thông Tin
Email:





<b>TRƯỞNG KHOA </b> <b>TỔ TRƯỞNG </b>


<b>BỘ MÔN </b> <b>CHỦ NHIỆM ĐỀ TÀI </b>


<b>Huỳnh Khắc Duy </b>
<b>HIỆU TRƯỞNG </b>



<b>DUYỆT </b>


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

<b> </b>


<b>TUYÊN BỐ BẢN QUYỀN </b>


Tài liệu này thuộc loại sách giáo trình nên các nguồn thơng tin có thể được phép
dùng ngun bản hoặc trích dùng cho các mục đích về đào tạo và tham khảo.


</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

<b>LỜI GIỚI THIỆU </b>


Giới thiệu xuất xứ của giáo trình, quá trình biên soạn, mối quan hệ của giáo trình với
chương trình đào tạo và cấu trúc chung của giáo trình.


Lời cảm ơn của các cơ quan liên quan, các đơn vị và cá nhân đã tham gia.


…………., ngày……tháng……năm………
Tham gia biên soạn


</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

<b>MỤC LỤC </b>


CHƯƠNG 1. WINDOWS CONTROLS ... 12


1.1 Tổng quan controls ... 12


1.2 Property & layout của control ... 12


1.3 Các control thông dụng ... 17



1.4 Mouse Even handling ... 47


1.5 Keyboard event handing ... 49


1.6 Tổng quan ứng dụng document Interface ... 54


1.7 Single Document Interface (SDI) ... 54


1.8 Multiple Document Interface (MDI) ... 55


1.9 GUI hỗ trợ ... 57


CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET ... 61


2.1. Tổng quan về ADO.NET ... 61


2.2. Các đối tượng trong ADO.NET ... 62


2.3. Đối tượng Command ... 66


2.4. Đối tượng DataAdapter ... 67


2.5. Đối tượng DataSet ... 68


CHƯƠNG 3. CÁC THÀNH PHẦN CỦA DATASET ... 70


3.1. Đối tượng DataTable ... 70


3.2. Đối tượng DataRow, DataColumn và DataRelation ... 70



CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU ... 78


4.1. ComboBox, ListBox, CheckListBox ... 78


4.2. DataGrid ... 92


CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG... 94


5.1. Xây dựng ứng dụng với mơ hình 3-layer ... 94


5.1.1. Tổ chức cây thư mục ... 95


5.1.2. Mơ hình đa tầng ... 97


5.1.3. Xây dựng lớp xử lý lưu trữ ... 98


5.1.4. Xây dựng các lớp xử lý nghiệp vụ ... 102


5.1.5. Hiển thị dữ liệu và thao tác trên màn hình ... 103


CHƯƠNG 6. CRYSTAL REPORT ... 109


6.1 Crystal report ... 109


6.1.1. Tạo mới report ... 109


6.1.2. Sử dụng crystal report để hiển thị report ... 112


6.1.3. Tạo nguồn dữ liệu cho report từ DataSet ... 113



6.1.4. Tạo nguồn dữ liệu cho report từ nguồn CSDL ... 114


6.1.5. Lọc dữ liệu trên report ... 114


6.1.6. Truyền tham số cho report ... 115


6.1.7. Xuất report ra máy in ... 115


6.1.8. Xuất report ra tập tin ... 116


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

CHƯƠNG 2:
<b> </b>


<b>GIÁO TRÌNH MƠN HỌC/MƠ ĐUN </b>
<b>Tên mơn học/mơ đun: Xây dựng ứng dụng Windows </b>


<b>Mã mơn học/mơ đun: MH3101344 </b>


<b>Vị trí, tính chất, ý nghĩa và vai trị của mơn học/mơ đun: </b>
- Vị trí: là mơn học chun ngành, học kỳ 4.


- Tính chất: mơn học lý thuyết, mơn bắt buộc.
- Ý nghĩa và vai trị của mơn học/mô đun:
<b>Mục tiêu của môn học/mô đun: </b>


- Về kiến thức:


+ Trình bày được về chức năng và cách thức sử dụng của các điều khiển
(windows controls) trong lập trình ứng dụng trên windows.



+ Trình bày được cách thức kết hợp sử dụng của các điều khiển trong lập trình
ứng dụng trên windows.


+ Thiết kế một ứng dụng windows forms cho một bài toán cụ thể.


+ Trình bày được thành phần của một ứng dụng có lien quan đến cơ sở dữ liệu
+ Nhận diện được các bước cần thiết để kết nối đến cơ sở dữ liệu từ ngôn ngữ


lập trình


+ Trình bày được các các phương pháp để tạo các biểu mẫu nhập dữ liệu thông
dụng


+ Trình bày được các các phương pháp để tạo các báo cáo.
- Về kỹ năng:


+ Xây dựng được các giao diện tương tác trực quan với người sử dụng
Windows.


+ Xây dựng một ứng dụng Winform hoàn chỉnh ở mức độ vừa phải sử dụng
công nghệ .NET


+ Gắn kết được các tương tác qua giao diện với các nguyên tắc nghiệp vụ để
kiểm tra tính hợp lệ của dữ liệu nhập.


+ Xây dựng được ứng dụng có sử dụng cơ sở dữ liệu.
+ Xây dựng được ứng dụng theo mơ hình 3-layer.
+ Lập được các báo cáo thống kê (Crystal Report).
- Về năng lực tự chủ và trách nhiệm:



+ Cẩn thận, nghiêm túc trong nghiên cứu.


+ Có khả năng xem các tài liệu hướng dẫn, đọc sách.
+ Cẩn thận và chính xác khi làm việc với cơ sở dữ liệu.


+ Khả năng phân tích và xây dựng một ứng dụng thông tin quản lý trên
windows.


<b>III. Nội dung môn học: </b>


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

<b>Số </b>


<b>TT </b> <b>Tên chương, mục </b>


<b>Thời gian (giờ) </b>
<b>Tổn</b>


<b>g số </b>
<b>Lý </b>


<b>thuyết </b> <b>Thực hành </b>


<b>Kiểm </b>
<b>Tra </b>


1


<b>Chương 1. Windows Controls </b>
1.1 Tổng quan controls



1.2 Property & layout của control
1.3 Các control thông dụng
1.4 Mouse Even handling
1.5 Keyboard event handing


1.6 Tổng quan ứng dụng document Interface
1.7 Single Document Interface (SDI)


1.8 Multiple Document Interface (MDI)
1.9 <b>GUI hỗ trợ </b>


15 10 5


2


<b>Chương 2. Tổng quan về ADO.NET </b>
2.1. Tổng quan về ADO.NET


2.2. Các đối tượng trong ADO.NET
2.3. Đối tượng Command


2.4. Đối tượng DataAdapter
<b>2.5. Đối tượng DataSet </b>


10 6 4


3


<b>Chương 3. Các thành phần của DataSet </b>


3.1. Đối tượng DataTable


3.2. Đối tượng DataRow, DataColumn và
DataRelation


10 6 2 2


4


<b>Chương 4. Các điều khiển liên kết dữ liệu </b>
4.1. ComboBox, ListBox, CheckListBox
4.2. DataGrid


10 6 4


5


<b>Chương 5. Xây dựng ứng dụng với mơ hình đa tầng </b>
5.1. Xây dựng ứng dụng với mơ hình 3-layer


5.1.1. Tổ chức cây thư mục
5.1.2. Mơ hình đa tầng


5.1.3. Xây dựng lớp xử lý lưu trữ


5.1.4. Xây dựng các lớp xử lý nghiệp vụ


5.1.5. Hiển thị dữ liệu và thao tác trên màn hình


15 8 5 2



6


<b>Chương 6. Crystal report </b>
6.1 Crystal report


6.1.1. Tạo mới report


6.1.2. Sử dụng crystal report để hiển thị report
6.1.3. Tạo nguồn dữ liệu cho report từ DataSet
6.1.4. Tạo nguồn dữ liệu cho report từ nguồn CSDL
6.1.5. Lọc dữ liệu trên report


6.1.6. Truyền tham số cho report


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

<b>Số </b>


<b>TT </b> <b>Tên chương, mục </b>


<b>Thời gian (giờ) </b>
<b>Tổn</b>


<b>g số </b>
<b>Lý </b>


<b>thuyết </b> <b>Thực hành </b>


<b>Kiểm </b>
<b>Tra </b>
6.1.7. Xuất report ra máy in



6.1.8. Xuất report ra tập tin
6.1.9. Đóng gói project


<b>Cộng </b> <b>75 </b> <b>45 </b> <b>26 </b> <b>4 </b>


<b>2. Nội dung chi tiết: </b>


<b>Chương 1. Windows Controls </b> <b>Thời gian: 15 giờ </b>


Mục tiêu:


- Trình bày được về chức năng và cách thức sử dụng của các điều khiển
(windows controls) trong lập trình ứng dụng trên windows.


- Trình bày được cách thức kết hợp sử dụng của các điều khiển trong lập trình
ứng dụng trên windows.


- Thiết kế một ứng dụng windows forms cho một bài toán cụ thể.
Nội dung:


1.1 Tổng quan controls


1.2 Property & layout của control
1.3 Các control thông dụng
1.4 Mouse Even handling
1.5 Keyboard event handing


1.6 Tổng quan ứng dụng document Interface
1.7 Single Document Interface (SDI)



1.8 Multiple Document Interface (MDI)
1.9 GUI hỗ trợ


<b>Chương 2. Tổng quan về ADO.NET </b> <b>Thời gian: 10 giờ </b>


Mục tiêu:


- Trình bày được các đối tượng của ADP.NET. Sử dụng được đối tượng
Connection để kết nối tới nguồn dữ lieu.


- Thực hiện được các thao tác trên nguồn dữ liệu bằng đối tượng Command.
- Sử dụng được đối tượng DataAdapter để lấy cấu trúc và dữ liệu của các bảng


trong nguồn dữ liệu.
Nội dung:


2.1. Tổng quan về ADO.NET
2.2. Các độ tượng trong ADO.NET
2.3. Đối tượng Command


2.4. Đối tượng DataAdapter
2.5. Đối tượng DataSet


<b>Chương 3. Các thành phần của DataSet </b> <b>Thời gian: 10 giờ </b>


</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

- Trình bày được các thành phần của đối tượng DataSet. Sử dụng được DataSet
để xây dựng ứng dụng.


Nội dung:



3.1. Đối tượng DataTable


3.2. Đối tượng DataRow, DataColumn và DataRelation


<b>Chương 4. Các điều khiển liên kết dữ liệu </b> <b>Thời gian: 10 giờ </b>


Mục tiêu:


- Trình bày được các thuộc tính các điều khiển lien kết dữ liệu.


- Trình bày được các phương thức của các điều khiển lien kết dữ liệu.
- Sử dụng được các điều khiển để xây dựng ứng dụng


Nội dung:


4.1. ComboBox, ListBox, CheckListBox
4.2. DataGrid


<b>Chương 5. Xây dựng ứng dụng với mơ hình đa tầng </b> <b>Thời gian: 15 giờ </b>
Mục tiêu:


- Trình bày được các kiến thức của mơ hình đa tầng.
- Sử dụng được mơ hình đa tầng để xây dựng ứng dụng.
Nội dung:


5.1. Xây dựng ứng dụng với mơ hình 3-layer
5.1.1. Tổ chức cây thư mục


5.1.2. Mơ hình đa tầng



5.1.3. Xây dựng lớp xử lý lưu trữ


5.1.4. Xây dựng các lớp xử lý nghiệp vụ


<b>5.1.5. Hiển thị dữ liệu và thao tác trên màn hình </b>


<b>Chương 6. Crystal report </b> <b>Thời gian: 15 giờ </b>


Mục tiêu:


- Trình bày được các kiến thwucs về Crystal Report
- Tạo được các kiểu Report


- Xây dựng được ứng dụng có sử dụng Report
- Đóng gói được một phần mềm.


Nội dung:


6.1 Crystal report
6.1.1. Tạo mới report


6.1.2. Sử dụng crystal report để hiển thị report
6.1.3. Tạo nguồn dữ liệu cho report từ DataSet
6.1.4. Tạo nguồn dữ liệu cho report từ nguồn CSDL
6.1.5. Lọc dữ liệu trên report


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

<b>IV. Điều kiện thực hiện mơn học: </b>


1. Phịng học chun mơn hóa/nhà xưởng: Phịng học thực hành.



2. Trang thiết bị máy móc: Máy chiếu, máy tính có phần mềm Visual Studio.
3. Học liệu, dụng cụ, nguyên vật liệu: Bảng, bút viết bảng.


4. Các điều kiện khác: máy tính có kết nối Internet.
<b>V. Nội dung và phương pháp, đánh giá: </b>


1. Nội dung:
- Kiến thức:


Được đánh giá qua bài kiểm tra và thực hành cuối mơn đạt được các u cầu
<i>sau: </i>


+ Trình bày được các thành phần của một ứng dụng có lien quan đến cơ sở
dữ liệu


+ Nhận diện được các bước cần thiết để kết nối đến cơ sở dữ liệu từ ngơn
ngữ lập trình


+ Trình bày được các các phương pháp để tạo các biểu mẫu nhập dữ liệu
thông dụng


+ Phương thức, thuộc tính của các đối tượng tương tác, xử lý dữ liệu trên
các cơ sở dữ liệu.


- Kỹ năng:


Đánh giá kỹ năng thực hành của sinh viên trong các bài thực hành:
+ Viết và thực thi ứng dụng ADO.Net.



+ Xây dựng được ứng dụng có sử dụng có sử dụng cơ sở dữ liệu.


+ Thực hiện các thao tác xử lý dữ liệu trên cơ sở dữ liệu: thêm mới, xóa,
sửa đổi, hiển thị,…


+ Xây dựng ứng dụng với mơ hình 3-layer.
- Năng lực tự chủ và trách nhiệm:


+ Cẩn thận, tự giác, kiên trì


+ Chấp hình các nội quy của phòng thực hành.
2. Phương pháp:


<b>STT </b> <b>Phương pháp </b> <b>Hình thức </b> <b>Số cột </b> <b>Thời gian </b>


<b>thi </b>
01 Kiểm tra thường xuyên Thực hành trên máy


tính 2


02 Kiểm tra định kỳ Thực hành trên máy


tính 2


90 phút


03 Thi kết thúc môn học Thực hành trên máy
tính


90 phút



<b>VI. Hướng dẫn thực hiện môn học: </b>


1. Phạm vi áp dụng môn học: Áp dụng cho khóa học trình độ cao đẳng.
2. Hướng dẫn về phương pháp giảng dạy, học tập mơn học:


</div>
<span class='text_page_counter'>(11)</span><div class='page_container' data-page=11>

+ Giáo viên có thể vận dụng phương pháp thuyết trình, giảng giải kết hợp
phương pháp gợi mở, phát vấn để người học nghề có thể tham gia tích cực vào
bài giảng.


+ Phương tiện, dụng cụ giảng dạy: Ngoài phương tiện giảng dạy truyền
thống giáo viên cịn có thể sử dụng Máy chiếu Projector, Laptop, sơ đồ, tranh
ảnh minh hoạ giúp làm rõ và sinh động nội dung bài học.


+ Trong điều kiện có thể kết hợp giảng dạy lý thuyết và thực hành trong
cùng một phịng học chun mơn hố có máy tính được nối mạng LAN và
mạng Internet, có sử dụng các phương tiện dạy học bằng hình ảnh.


- Đối với người học:


+ Thực hiện đầy đủ và nghiêm túc các qui định đối với môn học và của
giáo viên.


+ Hoàn thành đầy đủ các bài thực hành và tham dự các buổi kiểm tra trên
lớp.


+ Kết thúc khóa học, người học sẽ làm một bài kiểm tra để xác định việc
họ có hồn thành chương trình học hay khơng


+ Học sinh tham gia đầy đủ các buổi lên lớp (không nghỉ quá 30% thời


lượng học)


3. Những trọng tâm cần chú ý:


- <b>Trình độ giáo viên: ít nhất phải có bằng cử nhân hoặc bằng cấp tương </b>
đương tính theo kinh nghiệm dạy học trước đó. Có chứng chỉ dạy nghề.


- <b>Nguồn lực đào tạo: Những nguồn lực sau đây được khuyến khích sử dụng </b>
để bổ trợ những phương pháp giảng dạy đề xuất.


+ Cơ sở vật chất, trang thiết bị giảng dạy: Lớp học có đầy đủ máy vi tính cho
học sinh thực tập.


+ Sách, giáo trình và tài liệu tham khảo.


+ Kế hoạch giảng dạy và giáo án chi tiết của giáo viên đóng vai trị tài liệu
chính được sử dụng trong quá trình giảng dạy.


</div>
<span class='text_page_counter'>(12)</span><div class='page_container' data-page=12>

CHƯƠNG 2:


<b>CHƯƠNG 1. WINDOWS CONTROLS </b>


<b>1.1 Tổng quan controls </b>


Control là một thành phần cơ bản trên form


 Có các thành phần
o Thuộc tính
o Phương thức
o Sự kiện



 Tất cả các control chứa trong namespace:System.Windows.Forms
Một số thuộc tính của control


 Text: mơ tả text xuất hiện trên control


 Focus: phương thức chuyển focus vào control


 TabIndex: thứ tự của control nhận focus
o Mặc định được VS.NET thiết lập


 Enable: thiết lập trạng thái truy cập của control


 Visible: ẩn control trên form, có thể dùng phương thức Hide


 Anchor:


o Neo giữ control ở vị trí xác định
o Cho phép control di chuyển theo vị trí


 Size: xác nhận kích thước của control


<b>1.2 Property & layout của control </b>
Common Properties Description


BackColor Màu nền của control
BackgroundImage Ảnh nền của control
ForeColor Màu hiển thị text trên form


Enabled Xác định khi control trạng thái enable
Focused Xác định khi control nhận focus


Font Font hiển thị text trên control
TabIndex Thứ tự tab của control


TabStop Nếu true, user có thể sử dụng tab để select control


Text Text hiển thị trên form


</div>
<span class='text_page_counter'>(13)</span><div class='page_container' data-page=13>

 Khi FormBorderStyle = Sizable, form cho phép thay đổi kích thước khi Runtime
o Sự bố trí của control cũng thay đổi!


 Sử dụng thuộc tính Anchor


o Cho phép control phản ứng lại với thao tác resize của form


 Control có thể thay đổi vị trí tương ứng với việc resize của form


 Control cố định không thay đổi theo việc resize của form


 Các trạng thái neo


 Left: cố định theo biên trái


 Right: cố định theo biên phải


 Top: cố định theo biên trên


</div>
<span class='text_page_counter'>(14)</span><div class='page_container' data-page=14></div>
<span class='text_page_counter'>(15)</span><div class='page_container' data-page=15></div>
<span class='text_page_counter'>(16)</span><div class='page_container' data-page=16></div>
<span class='text_page_counter'>(17)</span><div class='page_container' data-page=17>

<b>1.3 Các control thông dụng </b>


<b>Label, TextBox, Button </b>
<b>Label </b>



- Cung cấp chuỗi thông tin chỉ dẫn
- Chỉ đọc


- Được định nghĩa bởi lớp Label
- Dẫn xuất từ Control


<b>TextBox </b>


- Thuộc lớp TextBox


- Vùng cho phép user nhập dữ liệu
- Cho phép nhập dạng Password
<b>Button </b>


- cho phép cài đặt 1 hành động.
- Checkbox và RadioButton
- Dẫn xuất từ ButtonBase


<b>Label </b>


Thuộc tính thường dùng


Font Font hiển thị của text


Text Nội dung text hiển thị


TextAlign Canh lề text


ForeColor Màu text



Visible Trạng thái hiển thị
<b>TextBox </b>


Thuộc tính thường dùng


AcceptsReturn Nếu true: nhấn enter tạo thành dòng mới <sub>trong chế độ multiline </sub>
Multiline Nếu true: textbox ở chế độ nhiều dòng, mặc <sub>định là false </sub>
PasswordChar Chỉ hiển thị ký tự đại diện cho text


ReadOnly Nếu true: textbox hiển thị nền xám, và ko
cho phép nhập liệu, mặc định là false
ScrollBars Thanh cuộn cho chế độ multiline


Event thường dùng
TextChanged


Kích hoạt khi text bị thay đổi, trình xử lý
được khởi tạo mặc định khi kích đúp vào
textbox trong màn hình design view


<b>Button </b>


Thuộc tính thường dùng


</div>
<span class='text_page_counter'>(18)</span><div class='page_container' data-page=18>

Click


Kích hoạt khi user kích vào button,
khai báo mặc định khi người lập trình
kích đúp vào button trong màn hình


Design View của Form.


Chỉ cho nhập số


<b>ListBox & ComboBox </b>
<b>ListBox </b>


</div>
<span class='text_page_counter'>(19)</span><div class='page_container' data-page=19></div>
<span class='text_page_counter'>(20)</span><div class='page_container' data-page=20>

Thuộc tính Items cho phép thêm item vào ListBox


</div>
<span class='text_page_counter'>(21)</span><div class='page_container' data-page=21>

Demo ListBox


Kiểm tra xem chuỗi nhập có trong list box?
- Nếu có: select item đó


- Ngược lại: thêm chuỗi mới vào list box
Sự kiện SelectedIndexChanged


<b>ComboBox </b>


</div>
<span class='text_page_counter'>(22)</span><div class='page_container' data-page=22></div>
<span class='text_page_counter'>(23)</span><div class='page_container' data-page=23></div>
<span class='text_page_counter'>(24)</span><div class='page_container' data-page=24>

Tính năng AutoComplete


<b>ListView </b>


Dạng control phổ biến hiện thị một danh sách item
- Các item có thể có các item con gọi là subitem
Windows Explorer hiển thị thông tin thư mục, tập tin…


- Có thể hiển thị thơng tin theo nhiều dạng thơng qua thuộc tính
View



o Xem dạng chi tiết thông tin
o Xem dạng icon nhỏ


o Xem dạng icon lớn
o Xem dạng tóm tắt


</div>
<span class='text_page_counter'>(25)</span><div class='page_container' data-page=25></div>
<span class='text_page_counter'>(26)</span><div class='page_container' data-page=26>

Large Icons


Mỗi item xuất hiện với 1 icon kích thước lớn và một label bên dưới


Small Icons


</div>
<span class='text_page_counter'>(27)</span><div class='page_container' data-page=27>

List


Mỗi item xuất hiện với icon nhỏ với label bên phải, item được sắp theo cột
nhưng khơng có tiêu đề cột


Tile


</div>
<span class='text_page_counter'>(28)</span><div class='page_container' data-page=28>

Detail


Mỗi item xuất hiện trên một dòng, mỗi dịng có các cột chứa thơng tin chi tiết


<b>List View </b>


</div>
<span class='text_page_counter'>(29)</span><div class='page_container' data-page=29>

Thêm các item vào ListView


 Thêm item trong màn hình thiết kế form


 Thêm item thông qua code


Các lớp định nghĩa Item


 System.Windows.Forms.ListViewItem


 Mỗi item trong ListView có các item phụ gọi là subitem


o Lớp ListViewItem.ListViewSubItem định nghĩa các subitem
của ListView


o Lớp ListViewSubItem là inner class của ListViewItem


</div>
<span class='text_page_counter'>(30)</span><div class='page_container' data-page=30>

Sự kiện SelectedIndexChanged


<b>GroupBox, Panel & TabControl </b>
Bố trí controls trên GUI


GroupBox


 Hiển thị một khung bao quanh một nhóm control


</div>
<span class='text_page_counter'>(31)</span><div class='page_container' data-page=31>

 Khi xóa một GroupBox thì các control chứa trong nó bị xóa theo


 Lớp GroupBox kế thừa từ System.Windows.Forms.Control
Panel


 Chứa nhóm các control


 Khơng có caption


 Có thanh cuộn (scrollbar)



o Xem nhiều control khi kích thước panel giới hạn


GroupBox Mơ tả


Thuộc tính thường dùng


Controls Danh sách control chứa trong GroupBox.


Text Caption của GroupBox


Panel


Thuộc tính thường dùng


AutoScroll Xuất hiện khi panel quá nhỏ để hiển thị hết các
control, mặc định là false


BorderStyle Biên của panel, mặc định là None, các tham số
khác như Fixed3D, FixedSingle


Controls Danh sách control chứa trong panel
Minh họa GroupBox


</div>
<span class='text_page_counter'>(32)</span><div class='page_container' data-page=32>

<b>TabControl </b>


 Dạng container chứa các control khác


 Cho phép thể hiện nhiều page trên một form duy nhất



 Mỗi page chứa các control tương tự như group control khác.
o Mỗi page có tag chứa tên của page


o Kích vào các tag để chuyển qua lại giữa các page


 Ý nghĩa:


o Cho phép thể hiện nhiều control trên một form


o Các control có cùng nhóm chức năng sẽ được tổ chức trong một
tab (page)


</div>
<span class='text_page_counter'>(33)</span><div class='page_container' data-page=33>

Thuộc tính Appearance


</div>
<span class='text_page_counter'>(34)</span><div class='page_container' data-page=34>

Thêm/Xóa TabPage


Chỉnh sửa các TabPage


 Chọn thuộc tính TabPages của TabControl


</div>
<span class='text_page_counter'>(35)</span><div class='page_container' data-page=35>

Bổ sung Control vào TabControl


 Chọn TabPage cần thêm control


 Kéo control từ ToolBox thả vào TabPage đã chọn


</div>
<span class='text_page_counter'>(36)</span><div class='page_container' data-page=36>

<b>CheckBox, CheckedListBox, RadioButton & TrackBar </b>
<b>CheckBox </b>


Control đưa ra một giá trị cho trước và user có thể



 Chọn giá trị khi Checked = true


 Không chọn giá trị: Checked = false
Lớp đại diện CheckBox


ThreeState = true : cho phép thiết lập 3 trạng thái:


 Checkstate = Indeterminate: không xác định


 CheckState= Checked: chọn


</div>
<span class='text_page_counter'>(37)</span><div class='page_container' data-page=37>

<b>RadioButton </b>


 Cho phép user chọn một option trong số nhóm option


 Khi user chọn 1 option thì tự động option được chọn trước sẽ uncheck


 Các radio button chứa trong 1 container (form, GroupBox, Panel,
TabControl) thuộc một nhóm.


 Lớp đại diện: RadioButton


</div>
<span class='text_page_counter'>(38)</span><div class='page_container' data-page=38>

<b>CheckedListBox </b>


Tương tự như list box nhưng mỗi item sẽ có thêm checkbox.


Thuộc tính Items lưu trữ danh sách item
Có thể bổ sung vào thời điểm



 Design time


 Run time


</div>
<span class='text_page_counter'>(39)</span><div class='page_container' data-page=39>

Sự kiện SelectedIndexChanged


<b>TrackBar </b>


</div>
<span class='text_page_counter'>(40)</span><div class='page_container' data-page=40>

Bổ sung Label hiển thị giá trị của TrackBar


PictureBox & ImageList
PictureBox


</div>
<span class='text_page_counter'>(41)</span><div class='page_container' data-page=41>

Các thuộc tính


 Image: ảnh cần hiển thị


 SizeMode:
o Normal
o StretchImage
o AutoSize
o CenterImage
o Zoom


</div>
<span class='text_page_counter'>(42)</span><div class='page_container' data-page=42>

Demo


<b>NumericUpDown & DomainUpDown </b>
<b>NumericUpDown </b>


Cho phép user chọn các giá trị trong khoảng xác định thông qua



 Nút up & down


 Nhập trực tiếp giá trị
Các thuộc tính


 Minimum


 Maximum


</div>
<span class='text_page_counter'>(43)</span><div class='page_container' data-page=43>

 Increment
Sự kiện


 ValueChanged
Phương thức


 DownButton


 UpButton


Đoạn code thêm control NumericUpDown


Demo


</div>
<span class='text_page_counter'>(44)</span><div class='page_container' data-page=44>

Cho phép user chọn item trong số danh sách item thông qua


 Button Up & Down


 Nhập từ bàn phím
Properties



 Items: danh sách item


 ReadOnly: true chỉ cho phép thay đổi giá trị qua Up & Down


 SelectedIndex: chỉ mục của item đang chọn


 SelectedItem: item đang được chọn


 Sorted: sắp danh sách item


 Text: text đang hiển thị trên DomainUpDown.
Event


 SelectedItemChanged
Nhập item cho DomainUpDown


Graphic & RichText Controls
DateTimePicker


Cho phép chọn ngày trong khoảng xác định thông qua giao diện đồ họa dạng
calendar


Kết hợp ComboBox và MonthCalendar
Properties


</div>
<span class='text_page_counter'>(45)</span><div class='page_container' data-page=45>

o long, short, time, custom


 CustomFormat:



o dd: hiển thị 2 con số của ngày
o MM: hiển thị 2 con số của tháng
o yyyy: hiển thị 4 con số của năm
o …(xem thêm MSDN Online)


 MaxDate: giá trị ngày lớn nhất


 MinDate: giá trị ngày nhỏ nhất


 Value: giá trị ngày hiện tại đang chọn


</div>
<span class='text_page_counter'>(46)</span><div class='page_container' data-page=46>

MonthCalendar


Cho phép user chọn một ngày trong tháng hoặc nhiều ngày với ngày bắt đầu và
ngày kết thúc


Một số thuộc tính thơng dụng


 MaxDate, MinDate


 SelectionStart: ngày bắt đầu chọn


 SelectionEnd: ngày kết thúc


RichTextBox


Chức năng mở rộng từ TextBox, có thể hiển thị text dạng rich text format
(RTF)


Các text có thể có các font chữ và màu sắc khác nhau.


Đoạn text có thể được canh lề


Có thể chứa các ảnh


</div>
<span class='text_page_counter'>(47)</span><div class='page_container' data-page=47>

<b>1.4 Mouse Even handling </b>


Sự kiện chuột với tham số kiểu EventArgs


MouseEnter Xuất hiện khi con trỏ chuột đi vào vùng biên của control
MouseLeave Xuất hiện khi con trỏ chuột rời khỏi biên của control


Sự kiện chuột với tham số kiểu MouseEventArgs
MouseDown/


MouseUp


Xuất hiện khi button được nhấn/thả và con trỏ chuột đang ở
trong vùng biên của control


MouseMove Xuất hiện khi chuột di chuyển và con trỏ chuột ở trong vùng
biên của control


Thuộc tính của lớp MouseEventArgs


Button Button được nhấn {Left, Right, Middle, none} có kiểu là
MouseButtons


Clicks Số lần button được nhấn


</div>
<span class='text_page_counter'>(48)</span><div class='page_container' data-page=48>

Demo thao tác: kích chuột trái tại một điểm A, giữ chuột trái và di chuyển


chuột, chương trình sẽ vẽ đường thẳng từ điểm A đến vị trí hiện tại chuột.
Các sự kiện cần xử lý


MouseDown:


 Xác định điểm A ban đầu
MouseMove


 Kiểm tra nếu Left button của chuột đang giữ


o Sử dụng Graphics để vẽ đường thẳng từ A đến vị trí hiện tại
Bước 1


</div>
<span class='text_page_counter'>(49)</span><div class='page_container' data-page=49>

Bước 2


Khai báo xử lý sự kiện MouseDown trong Form1


 Trong cửa sổ event của Form1, kích đúp vào sự kiện MouseDown


Bước 3


Cài đặt xử lý sự kiện MouseMove


 Kiểm tra nếu LeftButton được nhấn


o Vẽ đường thẳng từ pA đến vị trí hiện tại


<b>1.5 Keyboard event handing </b>


Phát sinh khi một phím được nhấn hoặc thả


Có 3 sự kiện


 KeyPress


 KeyUp


 KeyDown


KeyPress phát sinh kèm theo với mã ASCII của phím được nhấn


</div>
<span class='text_page_counter'>(50)</span><div class='page_container' data-page=50>

<b>Sự kiện với tham số kiểu KeyEventArgs </b>


KeyDown Phát sinh khi phím được nhấn
KeyUp Phát sinh khi phím được thả
<b>Sự kiện với tham số kiểu KeyPressEventArgs </b>


KeyPress Khởi tạo khi phím được nhấn
<b>Thuộc tính của lớp KeyPressEventArgs </b>


KeyChar Chứa ký tự ASCII của phím được nhấn


Handled Cho biết sự kiện KeyPress có được xử lý chưa
<b>Thuộc tính của lớp KeyEventArgs </b>


Alt, Control, Shift Trạng thái các phím bổ sung
Handled Cho biết sự kiện đã xử lý


KeyCode Trả về mã ký tự được định nghĩa trong Keys
enumeration



KeyData Chứa mã ký tự với thơng tin phím bổ sung
KeyValue Trả về số int, đây chính là mã Windows Virtual


Key Code


Modifier Trả về giá trị của phím bổ sung
Keys Enumeration


Minh họa các sự kiện: KeyPress, KeyDown, KeyUp


 Khi user nhấn một phím


o Bắt sự kiện KeyPress: xuất ra phím được nhấn


o Bắt sự kiện KeyDown: xuất ra các tham số trong KeyEventArgs


 Khi user thả phím


o Xóa các thơng tin mơ tả phím được nhấn trong các label
Cách thực hiện


 Tạo một form minh họa


 Thiết kế trên form có 2 Label:


o lblChar: hiển thị ký tự được nhấn trong KeyPress


</div>
<span class='text_page_counter'>(51)</span><div class='page_container' data-page=51>

Bước 1: tạo Windows Form như hình mơ tả


Bước 2: Tạo KeyPress Event Handling cho form



</div>
<span class='text_page_counter'>(52)</span><div class='page_container' data-page=52></div>
<span class='text_page_counter'>(53)</span><div class='page_container' data-page=53>

CT Calculator (BT3) mở rộng cho phép xử lý các phím


 Form nhận xử lý thông điệp KeyDown


 Xác định các phím tương ứng rồi gọi sự kiện click của button
o VD: user gõ phím 1, tương tự như button “1” được nhấn
Cách thực hiện


 Khai báo trình xử lý sự kiện KeyDown cho Form chính


 Thiết lập thuộc tính KeyPreviewcho Form để nhận sự kiện bàn phím.


Viết phần xử lý cho sự kiện KeyDown


</div>
<span class='text_page_counter'>(54)</span><div class='page_container' data-page=54>

<b>1.6 Tổng quan ứng dụng document Interface </b>
Dạng ứng dụng làm việc với các document:


Document chứa nội dung dữ liệu, được lưu trữ trên file hoặc trong CSDL.


Các dạng document: Soạn thảo văn bản; Xử lý ảnh đồ họa; Bảng tính; Làm việc csdl ...
Ứng dụng dạng DI sẽ cung cấp các chức năng


Mở file (hoặc CSDL), xử lý nội dung và lưu file (hoặc CSDL)
Có 2 dạng ứng dụng DI:


- Single Document Interface
- Multiple Document Interface
<b>1.7 Single Document Interface (SDI) </b>



Chỉ hỗ trợ một document hoặc một cửa sổ tại một thời điểm.


</div>
<span class='text_page_counter'>(55)</span><div class='page_container' data-page=55>

<b>1.8 Multiple Document Interface (MDI) </b>


Ứng dụng cho phép xử lý nhiều document tại một thời điểm.


Các ứng dụng hiện tại thường là dạng MDI: MS Office; MS Studio.NET; Adobe Photoshop


Ứng dụng MDI thường phức tạp và chức năng xử lý đa dạng


</div>
<span class='text_page_counter'>(56)</span><div class='page_container' data-page=56></div>
<span class='text_page_counter'>(57)</span><div class='page_container' data-page=57>

Đặc điểm của MDIParent Form


 Được sử dụng làm cửa sổ chính cho ứng dụng.


 Trong một ứng dụng chỉ có một cửa sổ MDI.


 Các cửa sổ con bên trong MDI chỉ có thể di chuyển trong phạm vi của cửa sổ
MDI chứa nó.


 Khi cửa sổ con bên trong MDI được maximize thì click thước cũng chỉ bằng vùng làm
việc của MDI


 Tiêu đề của cửa sổ con được ghép với tiêu đề của cửa sổ MDI. Nếu có menu, lúc này
menu của cửa sổ con sẽ thay thế menu của cửa sổ MDI.


 Khi cửa sổ con được minimize, biểu tượng của cửa sổ con nó nằm trong cửa sổ MDI.


<b>1.9 GUI hỗ trợ </b>
<b>MenuStrip </b>



Menu cung cấp nhóm lệnh có quan hệ với nhau cho các ứng dụng Windows


<i>T</i>


<i>ThhuuộộccttíínnhhccủủaaMMeennuuSSttrriipp,,TToooollSSttrriippMMeennuuIItteemm </i>


<i>M</i>


<i>MeennuuSSttrriip p</i>


Items Chứa những top menu item


MdiWindowListItem Chọn top menu item hiển thị tên các cửa sổ con


<i>T</i>


</div>
<span class='text_page_counter'>(58)</span><div class='page_container' data-page=58>

Checked Xác định trạng thái check của menu item
Index Chỉ mục menu item trong menu cha
DropDownItems Chứa những menu item con


ShortcutKeys Phím tắt


Text Tiêu đề menu item


ShowShortcutKeys Xác định trạng thái hiện thị phím tắt bên cạnh menu item


<b>ContextMenuStrip </b>


Xuất hiện khi user kích chuột phải



Thơng thường menu này xuất hiện tùy thuộc vào đối tượng trong vùng kích chuột phải.
Trong ToolBox kéo ContextMenuStrip thả vào form


Kích vào ContextMenuStrip để soạn thảo các menuitem
ContextMenuStrip tạm thời thể hiện trên cùng của form
Khi run thì sẽ khơng hiển thị cho đến khi được gọi
Khai báo sử dụng Context Menu


Mỗi control đều có property là: ContextMenuStrip
Khai báo thuộc tính này với ContextMenuStrip


Khi đó user kích chuột phải lên control thì sẽ hiển thị context Menu đã cài đặt sẵn
Khai báo trình xử lý sự kiện Click cho ContextMenu


Kích đúp vào menu item của Context Menu để tạo


Hoặc trong cửa sổ Properties -> Event kích đúp vào sự kiện Click.
<b>ToolStrip </b>


</div>
<span class='text_page_counter'>(59)</span><div class='page_container' data-page=59>

Cung cấp các button cho phép thực hiện các chức năng thường dùng trong menu
ToolStrip là dạng container cho phép chứa các control


Các control này dẫn xuất từ ToolStripItem
Các control bao gồm


ToolStripSplitButton
ToolStripDropDownbutton
ToolStripLabel



ToolStripProgressBar
ToolStripSeparator
ToolStripComboBox
ToolStripTextBox


Cách tạo button trên ToolStrip
Kéo ToolStrip thả vào form
Add ToolStripButton


<b>StatusStrip </b>


Hiển thị thông tin trạng thái của ứng dụng
Nằm bên dưới cùng của Form.


Các lớp liên quan


StatusStrip: là container chứa control khác


</div>
<span class='text_page_counter'>(60)</span><div class='page_container' data-page=60></div>
<span class='text_page_counter'>(61)</span><div class='page_container' data-page=61>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET </b>


<b>2.1. Tổng quan về ADO.NET </b>


Kiến trúc của ADO.NET được mô tả như hình dưới, bao gồm hai thành phần
chính:


Thành phần truy cập nguồn dữ liệu và thành phần lưu trữ xử lý dữ liệu.


<i>Thành phần thứ nhất:.NET Framework Data Provider được thiết kế để thực hiện </i>


các thao tác kết nối, gửi các lệnh xử lý đến CSDL (thành phần này còn được gọi với


một tên khác là lớp kết nối – Connectectivity Layer). Trong ADO.NET, có 4 đối tượng
chính với các chức năng cơ bản như sau:


 Connection: giúp thực hiện kết nối đến các CSDL


 Command: giúp truy cập đến CSDL và thực hiện các phát biểu SQL hay thủ
tục lưu


trữ sẵn (stored procedure) của CSDL


 DataReader: dùng để đọc nhanh nguồn dữ liệu, chỉ được duyệt tuần
tự theo chiều tiến của các record


 DataAdapter: dùng để chuyển dữ liệu truy vấn được cho các đối
tượng lưu trữ và xử lý (DataSet, DataTable). DataAdapter chủ yếu
thực hiện các thao tác như SELECT, INSERT, UPDATE,
DELETE


</div>
<span class='text_page_counter'>(62)</span><div class='page_container' data-page=62>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>
<b>Interface </b> <b>SQL Server </b>


<b>Provider </b>


<b>Oracle Provider </b> <b>OLEDB Provider ODBC Provider </b>
<b>IDbConnection </b> SqlConnection OracleConnection OledbConnection OdbcConnection
<b>IDbDataAdapter SqlDataAdapter OracleDataAdapter OledbDataAdapter OdbcDataAdapter </b>


<b>IDbCommand </b> SqlCommand OracleCommand OledbCommand OdbcCommand


<b>IDbDataReader </b> SqlDataReader OracleDataReader OledbDataReader OdbcDataReader



Để sử dụng data provider nào, chúng ta phải tiến hành khái báo using namspace
tương ứng. Chẳng hạn, using System.Data.SqlClient;


Ngoài những data provider mơ tả ở bảng trên, chúng ta có thể reference đến các
data provider khác khơng được tích hợp sẵn bởi ADO.NET trong Visual Studio .NET,
chẳng hạn như data provider dùng cho MySQL, Postgre, …


Thành phần thứ hai trong kiến trúc ADO.NET – DataSet – được xem như là
container dùng để lưu trữ đối tượng liên quan đến dữ liệu như DataTable,
DataRelation, DataView. Thành phần này còn được gọi là lớp không kết nối
(disconected layer).


DataSet như là một CSDL thu nhỏ tại máy client, có thể chứa các đối tượng
table, view, constaint, ralationship giữa các table, … Tất cả dữ liệu từ nguồn dữ liệu
thực sẽ được nạp vào DataSet dưới dạng các DataTable, đó là một snapshot của nguồn
dữ liệu thực. Khối dữ liệu này sẽ được chỉnh sửa độc lập, sau đó nếu cần sẽ được cập
nhật trở lại nguồn dữ liệu thực. Theo nguyên tắc này, chúng ta không cần duy trì kết
nối liên tục một cách khơng cần thiết với nguồn dữ liệu thực trong suốt quá trình thao
tác với nó.


<b>2.2. Các đối tượng trong ADO.NET </b>
<b>Mơ hình Kết nối </b>


</div>
<span class='text_page_counter'>(63)</span><div class='page_container' data-page=63>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>


Các bước điển hình để làm việc với đối tượng DataReader là như sau:


1. Tạo đối tượng Connection bằng cách truyền một chuỗi Connection string cho hàm
khởi dựng của nó.



2. Khởi tạo một biến chuỗi và gán cho câu lệnh SQL dựa theo dữ liệu muốn nạp về.
3. Khởi tạo một đối tượng Command từ với nội dung câu lệnh SQL đã xác định ở
trên.


4. Tạo đối tượng DataReader bằng cách thực thi phương thức
Command.ExecuteReader(). Đối tượng này sau đó sẽ được dùng để đọc kết quả của
câu truy vấn mỗi dòng một lần.


Đoạn code sau minh họa các bước trên với Data Provider SqlClient. Đoạn code sẽ đọc
danh sách họ tên các sinh viên trong một bảng SinhVien của cơ sở dữ liệu và hiển thị
lên một điều khiển ListBox. Chi tiết về các đối tượng DataReader, Command,
Connection sẽ được đề cập chi tiết sau.


Tham số được sử dụng trong phương thức ExecuteReader xác định đối tượng
Connection sẽ được đóng sau khi DataReader được đóng.


<b>Mơ hình Ngắt Kết nối </b>


Triết lý của mơ hình Ngắt kết nối đó là: Dữ liệu được nạp – sử dụng một lệnh SQL –
từ nguồn dữ liệu bên ngoài vào bộ nhớ đệm tại máy client; tập kết quả được xử lý tại
máy cục bộ; mọi cập nhật sau đó sẽ được truyền từ dữ liệu trong bộ nhớ ngược trở lại
nguồn dữ liệu.


Mơ hình được gọi là “ngắt kết nối” bởi vì đối tượng kết nối chỉ được mở đủ lâu để đọc
dữ liệu từ nguồn dữ liệu và tiến hành các thao tác cập nhật. Bằng cách đưa dữ liệu về
phía máy client, tài nguyên của server – chẳng hạn như thông tin dữ liệu Connection,
bộ nhớ, thời gian xử lý – sẽ được giải phóng bớt. Tuy vậy, mơ hình này cũng có nhược
điểm về thời gian cần để nạp tập dữ liệu và bộ nhớ dùng để chứa dữ liệu tại máy client.
Như hình dưới đây minh họa, các thành phần chính của mơ hình ngắt kết nối đó là


DataApdapter và DataSet. DataAdapter làm nhiệm vụ như là cầu nối giữa nguồn dữ
liệu và DataSet, nạp dữ liệu vào các bảng của DataSet và đẩy các thay đối ngược trở
lại nguồn




</div>
<span class='text_page_counter'>(64)</span><div class='page_container' data-page=64>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>


Trong số các phương thức và thuộc tính của DataAdapter thì Fill() và Update() là hai
phương thức quan trọng nhất. Fill() chuyển một query đến cơ sở dữ liệu và lưu tập kết
quả trả về trong một DataTable nào đó; phương thức Update() thực hiện một thao tác
thêm, xóa, cập nhật dựa trên những thay đối của đối tượng DataSet. Các lệnh cập nhật
thực sự được chứa trong các thuộc tính của DataAdapter. Chi tiết về DataAdapter sẽ
được đề cập ở phần sau.


Để minh họa cách thức làm việc với DataAdapter và DataSet, đoạn code dưới đây giới
thiệu cách tạo ra một đối tượng DataTable, nạp dữ liệu từ một cơ sở dữ liệu, và đưa nó
vào một DataSet.




Trong số các phương thức và thuộc tính của DataAdapter thì Fill() và Update() là hai
phương thức quan trọng nhất. Fill() chuyển một query đến cơ sở dữ liệu và lưu tập kết
quả trả về trong một DataTable nào đó; phương thức Update() thực hiện một thao tác
thêm, xóa, cập nhật dựa trên những thay đối của đối tượng DataSet. Các lệnh cập nhật
thực sự được chứa trong các thuộc tính của DataAdapter. Chi tiết về DataAdapter sẽ
được đề cập ở phần sau.


Để minh họa cách thức làm việc với DataAdapter và DataSet, đoạn code dưới đây giới
thiệu cách tạo ra một đối tượng DataTable, nạp dữ liệu từ một cơ sở dữ liệu, và đưa nó


vào một DataSet.


Bước đầu tiên là tạo ra một thể hiện của SqlDataAdapter bằng cách truyền một câu
lệnh SELECT và chuỗi kết nối cho phương thức khởi dựng của lớp này. DataAdapter
sẽ lo đến việc tạo ra đối tượng Connection cũng như việc mở, đóng Connection khi
cần thiết. Sau khi một DataSet rỗng sẽ được tạo ra, phương thức Fill() của
DataAdapter sẽ tạo ra một DataTable có tên là “SinhVien” trong DataSet và nạp các
dòng dữ liệu vào DataTable này (bằng câu lện SQL dạng SELECT của DataAdapter).
Mỗi column của DataTable sẽ tương ứng với một column trong bảng của cơ sở dữ liệu
nguồn. Dữ liệu trong bảng dữ liệu sau đó được đưa vào một ListBox bằng cách duyệt
qua danh sách các dòng của DataTable.


<b>Lớp Connection </b>


</div>
<span class='text_page_counter'>(65)</span><div class='page_container' data-page=65>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>


<b>Loại </b> <b>Tên </b> <b>Mô tả </b>


<b>Property ConnectionString </b> Get/Sets chuỗi kết nối đến data source.


<b>Property ConnectionTimeout Khoảng thời gian tối đa tính bằng giây để chờ thực hiện </b>
việc kết nối đến data source


<b>Property Database </b> Tên CSDL ứng với Connection hiện tại


<b>Property State </b> Trạng thái hiện tại của Connection. Trả về một giá trị
kiểu liệt kê (enumeration): Broken, Closed, Connecting,
Executing, Fetching, hoặc Open


<b>Method </b> Open


Close


Mở một Connection. Roll back mọi thao tác đang làm
dở.


Đóng Connection – trả Connection cho Connection
Pool nếu như có sử dụng Connection Pool


<b>Method </b> BeginTransaction Khởi tạo một database transaction


<b>Method </b> ChangeDatabase Thay đối CSDL hiện tại cho Connection đang mở.
Chuỗi mô tả tên CSDL mới được truyền cho
phương thức này


<b>Method </b> CreateCommand Tạo ra một đối tượng Command ứng với Connection


<b>Connection string </b>


Thuộc tính ConnectionString xác định data source và các thông tin cần thiết để truy
xuất data source, chẳng hạn như User ID và Password, … Ngồi những thơng tin cơ
bản này, Connection string cịn có thể chứa các giá trị cho các trường dữ liệu đặc trưng
cho data provider. Ví dụ, Connection string cho Ms Sql Server có thể chứa các giá trị
để quy định Connection Timeout và Packet Size.


Dưới đây là các ví dụ về cách thành lập chuỗi kết nối cho các data provider thường
gặp. Danh sách đầy đủ về cách thành lập các chuỗi kết nối được cho ở Error!
Reference source not found..


• SqlConnection sử dụng cơ chế xác thực kiểu SQL Server:
“server=(1);database=(2);uid=(3);pwd=(4)” hoặc



“Data Source=(1);Initial Catalog=(2);User ID=(3);Password=(4)”


• SqlConnection sử dụng cơ chế xác thực kiểu Windows:
“Server=(1);Database=(2);Trusted_Connection=yes”


Ở đây, (1) là tên/máy chủ chứa CSDL, (2) là tên CSDL, (3) là tên đăng nhập, (4) là
mật khẩu tương ứng.


Ví dụ: “server=192.168.0.1;database=qlnhanvien;uid=k28;pwd=spider ”
hoặc


</div>
<span class='text_page_counter'>(66)</span><div class='page_container' data-page=66>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>


SqlConnection conn = new SqlConnection(connstr);
conn.open();


string sql =


"INSERT INTO SinhVien (MaSinhVien, HoTen) VALUES (@pMaSinhVien, @pHoTen)";
SqlCommand cmd = new SqlCommand();


cmd.Connection = conn;
cmd.commandText = sql;


cmd.Parameters.AddWithValue ("@pMaSinhVien", 12);
cmd.Parameters.AddWithValue ("@pHoTen", "tnv spider");


string provider = "System.Data.SqlClient";



DBProviderFactory factory = DbProviderFactories.GetFactory(provider);


DbCommand cmd = factory.CreateCommand(); // DbCommand là một lớp trừu tượng
cmd.CommandText = sql; // sql là một chuỗi query hay command


cmd.Connection = conn; // conn là một Connection
<b>2.3. Đối tượng Command </b>


Sau khi một đối tượng connection được tạo ra, bước tiếp theo trong quá trình truy xuất
CSDL – đối với mơ hình Kết nối – đó là tạo ra một đối tượng Command để gửi một
query (select) hay một action command (thêm, xóa, sửa) đến data source. Có nhiều
loại lớp Command ứng với các data provider; các lớp này đều implement interface
IDbCommand.


<b>Tạo đối tượng Command </b>


Bạn có thể dùng một trong nhiều hàm khởi dựng để tạo đối tượng Command một cách
trực tiếp hoặc sử dụng cách tiếp cận ProviderFactory.


Đoạn code dưới đây minh họa các tạo ra một đối tượng Command và thiết lập các
thuộc tính của nó.


Trong trường hợp ứng dụng có thể phải sử dụng nhiều data provider, bạn nên sử dụng
cách tiếp cận provider factory. Factory được tạo ra bằng cách truyền chuỗi data
provider cho hàm khởi dựng của nó. Tiếp đến, phương thức CreateCommand được gọi
để trả về một đối tượng command.


<b>Thực thi một Command </b>


Lệnh SQL được gán trong thuộc tính CommandText của đối tượng Command sẽ được


thực thi bằng một trong các phương thức được chỉ ra ở bảng dưới đây


<b>ExecuteNonQuery </b> Thực thi truy vấn hành động (action query) và trả về số
lượng


dòng dữ liệu bị ảnh hưởng bởi truy vấn đó:


cmd.CommandText = "DELETE SinhVien WHERE
MaSinhVien=12";


</div>
<span class='text_page_counter'>(67)</span><div class='page_container' data-page=67>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>


<b>ExecuteScalar </b> Thực thi một query và trả về giá trị của cột đầu tiên trong dòng đầu
tiên của tập kết quả.


cmd.CommandText="SELECT COUNT(MaSinhVien) FROM
SinhVien";


int soSinhVien = (int)cmd.ExecuteScalar();
DataReader để có thể truy cập tập kết quả của
query đó. Phương thức này nhận một tham số tùy
chọn kiểu CommandBehavior để có thể tăng hiệu
năng thực thi query.


cmd.CommandText = "SELECT * FROM
SinhVien” + “WHERE YEAR(NgaySinh) >
1981”;


ExecuteXmlReader Chỉ có cho data provider SQL Server. Trả về một đối tượng
XmlReader dùng để truy xuất tập dữ liệu. Tham khảo thông tin về XmlReader trong


MSDN


ExecuteReader là phương thức quan trọng nhất trong các phương thức kể trên. Phương
thức này trả về một đối tượng DataReader giúp truy xuất đến các dòng dữ liệu trả về
bởi query.


<b>2.4. Đối tượng DataAdapter </b>


DataAdapter là đối tượng làm trung gian lấy dữ liệu về cho DataSet, để DataSet thực
hiện xử lý ngắt kết nối. Do vậy, mặc dù DataAdapter được liệt kê là đối tượng hướng
kết nối nhưng thực chất nó phục vụ cho việc ngắt kết nối. Hay nói cách khác, để lầy dữ
liệu từ nguồn dữ liệu về cho ứng dụng, chúng ta sử dụng một đối tượng gọi là
DataAdapter. Đối tượng này cho phép ta lấy cấu trúc và dữ liệu của các bảng trong
nguồn dữ liệu.


Các đối tượng không kết nối (hay các đối tượng chứa dữ liệu) cho phép
– Lưu trữ một bản sao thông tin lấy từ cơ sở dữ liệu.


– Khi đã ngắt kết nối tới cơ sở dữ liệu.
– Đọc các dòng theo thứ tự bất kỳ


– Tìm kiếm, sắp xếp hay trích lọc các dịng một cách linh hoạt.


– Tạo ra các thay đổi trên dữ liệu, sau đó đồng bộ (cập nhật) các thay đổi này vào cơ
sở dữ liệu.


Cầu nối giữa các lớp kết nối và các lớp không kết nối là DataAdapter
<b> DataAdapte là một bộ gồm 4 đối tượng: </b>


 <b>SelectCommand: Cho phép lấy thông tin từ nguồn dữ liệu về. </b>



</div>
<span class='text_page_counter'>(68)</span><div class='page_container' data-page=68>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>


 <b>UpdateCommand: Cho phép điều chỉnh dữ liệu của bảng trong nguồn dữ liệu. </b>


 <b>DeleteCommand: Cho phép xóa dữ liệu của bảng trong nguồn dữ liệu. </b>
<b>Tạo DataAdapter </b>


Khai báo rõ DataAdapter sử dụng theo DataProvider nào: sqlDataAdapter hay
OledbDataAdapter hai lớp này thuộc tên miền:


 System.Data.OleDb.OleDbDataAdapter


 System.Data.SqlClient.SqlDataAdapte
<b>Các thuộc tín chính của DataAdapter </b>


 <b>DeleteCommand : Đối tượng Command chứa nội dung lệnh hủy các mẫu tin </b>
trên nguồn dữ liệu.


 <b>InsertCommand : Đối tượng Command chứa nội dung lệnh thêm các mẫu tin </b>
trên nguồn dữ liệu.


 <b>SelectCommand: Đối tượng Command chứa nội dung lệnh truy xuất các mẫu </b>
tin trên nguồn dữ liệu.


 <b>UpdateCommand : Đối tượng Command chứa nội dung lệnh sửa các mẫu tin </b>
trên nguồn dữ liệu.


<b>Các phương thức của DataAdapter </b>



 Lấy dữ liệu từ nguồn: Sử dụng DataAdapter để lấy dữ liệu về cho các đối tượng
o DataTable: Fill(<DataTable>)


o DataSet: Fill(<DataSet>) -->Dữ liệu lấy về DataSet dưới dạng các
dataTable với tên mặc định là: Table,Table1, Table2. . .:


 Đổ dữ liệu vào Datset cho bảng DataTable nếu chưa có sẽ tạo mới:


o Fill(<DataSet>,<Tên dataTable>)


 Phương thức trả về mẫu tin lấy về được


DataSet DS = New Dataset();
int so= DA.Fill(DS,”Sinhvien”) ;


 Để cập nhật dữ liệu về nguồn


o Update(<mảng dòng>): Cập nhật các dòng (Các đối tượng DataRow)
vào nguồn dữ liệu.


o Update(<Dataset>): Cập nhật các thay đổi trên tất cả các bảng của
Dataset vào nguồn dữ liệu.


o Update(<DataTable>): Cập nhật tất cả các thay đổi trên DataTable vào
nguồn dữ liệu.


o Update(<Dataset>,<Tên bảng>) Cập nhật các they đổi trên bảng trong
Dataset vào nguồn dữ liệu.


<b>2.5. Đối tượng DataSet </b>



</div>
<span class='text_page_counter'>(69)</span><div class='page_container' data-page=69>

<b>CHƯƠNG 2. TỔNG QUAN VỀ ADO.NET</b>


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.


</div>
<span class='text_page_counter'>(70)</span><div class='page_container' data-page=70>

<b>CHƯƠNG 3. CÁC THÀNH PHẦN CỦA DATASET </b>



<b>3.1. </b> <b>Đối tượng DataTable </b>


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.


<b>3.2. </b> <b>Đối tượng DataRow, DataColumn và DataRelation </b>
<b>DataRows </b>


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);
tb.AcceptChanges();


Console.Write(row.RowState);
tb.Rows[0].Delete();


// Undo deletion tb.RejectChanges();
tb.RejectChanges();


Console.Write(tb.Rows[0].RowState); // Unchanged DataRow myRow;
MyRow = tb.NewRow(); // Detached



</div>
<span class='text_page_counter'>(71)</span><div class='page_container' data-page=71>

đá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 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:


</div>
<span class='text_page_counter'>(72)</span><div class='page_container' data-page=72>

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
<b>DataColumn </b>


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ả


DataType Kiểu của dữ liệu chứa trong column này
Ví dụ: col1.DataType =


System.Type.GetType("System.String")



ReadOnly Cho biết giá trị của column có được chỉnh sửa hay không
Phương thức Mô tả


Unique Giá trị Boolean cho biết column này có được chứa các giá trị
trùng nhau


hay không


Caption Tiêu đề hiển thị trong thành phần điều khiển giao diện đồ họa
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());
}


DataTable Tên của đối tượng DataTable chứa column này


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";


AllowDBNull Giá trị Boolean cho biết column này có được chứa giá trị NULL hay
khơng


</div>
<span class='text_page_counter'>(73)</span><div class='page_container' data-page=73>

Để ý 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.


<b>DataRelation </b>
Tạo DataRelation:


Khi bạn thêm các table vào DataSet thì giữa chúng chưa có relation nào. Để tạo ra một
relation, bạn sử dụng property Relations của DataSet để thêm vào các đối tượng
DataRelation. Ví dụ sau tạo ra một relation giữa hai table Group, User trong DataSet
thông qua cột GroupID trong mỗi table với tên relation mà tôi đặt là Group_User.
DataSet dataSet = LoadData();


DataTable userTable = dataSet.Tables["User"];
DataTable groupTable = dataSet.Tables["Group"];
DataRelation relation=new DataRelation("Group_User",
groupTable.Columns["GroupID"],


userTable.Columns["GroupID"]);
dataSet.Relations.Add(relation);
Phương thức GetChildRows():



Sau khi có relation, ta có thể dùng phương thức instance DataRow.GetChildRows() để
lấy về một mảng các DataRow trong bảng con của bảng hiện tại.


</div>
<span class='text_page_counter'>(74)</span><div class='page_container' data-page=74>

DataRow[] memberRows = groupRows[0].GetChildRows("Group_User");
foreach (var row in memberRows)


Console.WriteLine(row["UserName"]);
Output:
Adon
Balrog
Bison
Cammy
ChunLi
Dan
DeeJay


Dòng lệnh đầu tiên của đoạn mã trên lấy về một mảng DataRow bằng phương thức
DataTable.Select(string filterExpression) với tham số là một câu lệnh lọc (giống biểu
thức sau từ khóa “where” trong SQL).


Dựa vào dữ liệu, ta biết mảng này thực chất chỉ chứa một phần tử, chính vì thế ta lấy
phần tử đầu tiên của mảng groupRows và gọi phương thức GetChildRows(string
relationName). Và kết quả in ra màn hình sẽ là những user nằm trong GroupID là 1,
tức là “Member”.


Phương thức GetParentRow():


Ngược với GetChildRows(), phương thức GetParentRow() trả về một DataRow từ
bảng cha của bảng hiện tại dựa vào relation giữa chúng. Ví dụ sau cho thấy


GroupName của user có UserID là “8”:


DataRow[] childRows = userTable.Select("UserID='8'");


DataRow parentRow = childRows[0].GetParentRow("Group_User");
Console.WriteLine(parentRow["GroupName"]);


Output:
Admin


</div>
<span class='text_page_counter'>(75)</span><div class='page_container' data-page=75>

DataTable có thể dùng một hoặc nhiều DataColumn để tạo ra một Primary Key.
Primary Key là định danh phân biệt các DataRow và tránh trùng lặp dữ liệu. Dựa vào
PrimaryKey, bạn mới có thể dùng phương thức Find() của DataRowCollection.


Đoạn code bên dưới sẽ tìm và trả về dịng dữ liệu với UserID là “1” trong table User:
DataColumn[] primaryKeys=new DataColumn[] { table.Columns["UserID"] };
table.PrimaryKey = primaryKeys;


DataRow row = table.Rows.Find("1");
Console.WriteLine(row["UserName"]);
// Ouput: Adon


Data Constraint trong DataTable


Constraint là các “luật lệ” mà bạn có thể đặt cho DataColumn nhằm hạn chế và đảm
bảo một vài quy tắc nào đó. Có hai loại constraint mà bạn có thể sử dụng:


– UniqueConstraint: Các giá trị của cột phải là unique (duy nhất).


– ForeignKeyConstraint: Duy trì liên kết giữa các DataTable trong DataSet.


Hai lớp này đều thừa kế từ lớp abstract Constraint:


UniqueConstraint:


DataTable userTable = dataSet.Tables["User"];


Constraint constraint=new UniqueConstraint(userTable.Columns["UserID"],true);
userTable.Constraints.Add(constraint);


Ví dụ trên sẽ tạo constraint cho cột UserID của table User. Tham số thứ hai của
constructor UniqueConstraint chỉ ra cột được sử dụng có phải là primary key khơng.
Vì tơi đặt là true, cột UserID này sẽ trở thành primary key của table này. Bạn có thể
đặt thêm UniqueConstraint này cho bất kì cột nào muốn bảo đảm giữ liệu không trùng
nhau.


</div>
<span class='text_page_counter'>(76)</span><div class='page_container' data-page=76>

Để xem DataTable có các constraint nào, bạn chỉ cần lặp qua các phần tử trong
collection DataTable.Constraint.


ForeignKeyConstraint


Constraint này được dùng để tạo relation giữa hai cột thuộc hai table (tạo foreign key
cho bảng). ForeignKeyConstraint phải được thêm vào table con vì đây là table chứa
foreign key


. Ví dụ ta tạo constraint này cho cột GroupID của hai table Group và User:
DataColumn parent = dataSet.Tables["Group"].Columns["GroupID"];
DataColumn child = dataSet.Tables["User"].Columns["GroupID"];


ForeignKeyConstraint constraint = new ForeignKeyConstraint("FK_Group_User",
parent, child);



constraint.UpdateRule = Rule.Cascade;
constraint.DeleteRule = Rule.SetNull;


dataSet.Tables["User"].Constraints.Add(constraint);


Sau khi đặt constraint này, nếu thử thêm một user có GroupID khơng nằm trong table
Group, bạn sẽ nhận được một exception “InvalidConstraintException”


dataSet.Tables[“User”].Rows.Add(13, “Test”, 999);


InvalidConstraintException: ForeignKeyConstraint FK_Group_User requires the child
key values (99) to exist in the parent table.


Một điểm chú ý là constraint này không tương đương với việc bạn đặt relation trong
DataSet. Vì vậy bạn khơng thể dùng các phương thức GetChildRows(),
GetParentRow().


Enum Rule


Enum này có bốn giá trị mà bạn có thể sử dụng, theo mơ tả dưới đây.
Rule setting Description


Cascade Delete or update related rows.


SetNull Set values in related rows to DBNull.


</div>
<span class='text_page_counter'>(77)</span><div class='page_container' data-page=77>

None Take no action on related rows. This is the default.


Như ví dụ trên, thuộc tính UpdateRule của constraint được đặt mặc định là


Rule.Cascade để nếu có thay đổi từ table cha, các dòng tương ứng trong table con sẽ tự
động cập nhật lại. Hoặc các dòng dữ liệu tương ứng trong table con sẽ bị xóa nếu như
table cha xóa một dịng dữ liệu.


Bạn thử sửa GroupID đầu tiên của table Group từ 1 thành 9. Sau đó kiểm tra lại table
User xem các dịng có GroupID ban đầu là 1 có chuyển thành 9 không:


dataSet.Tables["Group"].Rows[0]["GroupID"] = 9;


foreach(DataRow row in dataSet.Tables["User"].Select("GroupID='9'"))
Console.WriteLine(row["UserName"]);


Output:
Adon
Balrog
Bison
Cammy
ChunLi
Dan
DeeJay


</div>
<span class='text_page_counter'>(78)</span><div class='page_container' data-page=78>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU

<b>CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU </b>


<b>4.1. ComboBox, ListBox, CheckListBox </b>


<b>ComboBox </b>


<b>Một ComboBox hiển thị như một Textbox kết hợp với một Listbox, cho phép người </b>
dùng lựa chọn các mục từ danh sách hoặc nhập một giá trị mới.



<b>THUỘC TÍNH CỦA COMBOBOX </b>


</div>
<span class='text_page_counter'>(79)</span><div class='page_container' data-page=79>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU


Thuộc tính cơ bản của Control


</div>
<span class='text_page_counter'>(80)</span><div class='page_container' data-page=80>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
Với:


<b>- Simple: hiện ngay list item có sẵn. </b>


<b>- DropDownList: là danh sách hiện ra cố định, không thể tự nhập/chỉnh sửa item </b>
trong ComboBox.


<b>- DropDown: có thể thêm item mới bằng tay và chỉnh sửa Item đã chọn. </b>
Các bạn hãy thử chỉnh sửa các thứ này ngay trong code của mình:


<i><b>Vd: comboBox1.DropDownStyle = ComboBoxStyle.DropDown; </b></i>
<b> </b>


<b> - MaxDropDownItems: Xác định số lượng Item tối đa khi mở danh sách sẽ hiện ra </b>
cho các bạn


<b>PHƯƠNG THỨC CỦA COMBOBOX </b>


Phương thức thường thấy nhất là các phương thức thêm/xóa/sửa dữ liệu trong
<b>ComboBox. Để thêm vào ta dùng phương thức Add, để xóa tất cả Item đã thêm ta </b>
<b>dùng phương thức Clear, để xóa item cụ thể ta dùng phương thức Remove,... </b>


//Thêm dữ liệu



comboBox1.Items.Add("IceTea Việt");


comboBox1.Items.Add("Lập trình cuộc sống");
comboBox1.Items.Add("Xe đạp");


//Xóa dữ liệu cụ thể bằng chính Text của dữ liệu đó
comboBox1.Items.Remove("Xe đạp");


//Ta cũng có thể xóa theo chỉ số của item đó trong List dữ liệu


comboBox1.Items.RemoveAt(2); //Xóa item thứ 3 trong dữ liệu, vì 2 là index


<b> LẤY DỮ LIỆU TỪ COMBOBOX: </b>


Có thể lấy dữ liệu băng nhiều cách, tham khảo đoạn code sau
//Lấy trực tiếp từ thuộc tính Text của ComboBox


//Nhưng nếu ComboBox chưa được chọn thì sẽ khơng có giá trị
string var;


var = comboBox1.Text;


//Lấy giá trị qua thuộc tính SelectedItem


var item = this.comboBox1.GetItemText(this.comboBox1.SelectedItem);
//Hoặc lấy theo Text mình muốn


var item = this.comboBox1.GetItemText(this.comboBox1.FindStringExact("Xe


đạp"));


<b>SỰ KIỆN CỦA COMBOBOX </b>
Sự kiện của ComboBox không nhiều, sự kiện mặc định của nó


<b>là comboBox_SelectedIndexChanged, xảy ra khi chúng ta chọn một Item mới trong </b>
ComboBox.


</div>
<span class='text_page_counter'>(81)</span><div class='page_container' data-page=81>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
đề muốn nói về ComboBox nữa, thơi thì để bài sau vậy.


Như thường lệ là một đoạn code để các bạn đốn kết q. Đoạn này có vẻ dễ nhỉ :D
private void Form1_Load(object sender, EventArgs e)


{


comboBox1.Items.Add("weekdays");
comboBox1.Items.Add("year");
}


private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{


comboBox2.Items.Clear();


if (comboBox1.SelectedItem == "weekdays")
{


comboBox2.Items.Add("Sunday");
comboBox2.Items.Add("Monday");


comboBox2.Items.Add("Tuesday");
}


else if (comboBox1.SelectedItem == "year")
{
comboBox2.Items.Add("2012");
comboBox2.Items.Add("2013");
comboBox2.Items.Add("2014");
}
}



Bằng cách kết hợp Textbox và một danh sách drop-down thông thường, Combobox
đại diện cho một control thực sự hữu ích, một hybrid widget trong C# Winform. Nó
cũng tạo ra ý tưởng về các hộp thoại dialogs, nơi mà sẽ có các gợi ý cho người dùng từ
danh sách drop-down và lại chấp nhận được tất cả giá trị input bất kì


<b>ListBox </b>


Điều khiển ListBox dùng để hiển thị một danh sách các giá trị và người dùng có thể
<i>thao tác trên các phần tử của danh sách như: Thêm, xóa, chọn, tìm kiếm,….. </i>


<b>* Các thuộc tính thường dùng: </b>
<b>Tên thuộc tính </b> <b>Diễn giải </b>
Name Tiền tố là lst


Enabled Kích hoạt hoặc làm mờ điều khiển
DataSource Quy định dũ liệu nguồn khi truy



xuất CSDL


</div>
<span class='text_page_counter'>(82)</span><div class='page_container' data-page=82>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
SelectedIndex Trả về vị trí phần tử đang chọn


SelectedMod Lựa chọn phần tử trong danh sách
Locked Khóa điều khiển ở chế độ thiết kế
Visible Hiển thị hoặc ẩn ListBox


MultiColumn Tùy chọn hiển thị nhiều cột
<b>* Tìm hiểu về tập hợp Items: </b>


<b> Add: Thêm 1 phần tử vào danh sách, sử dụng phương thức: Items.Add </b>
<b> Count: Trả về số mục (Item) có trong danh sách: Items.Count; </b>


<b> Remove: Xóa đối tượng Item tại ra khỏi danh sách: Items.Remove(<Chuoi>); </b>


 Trong trường hợp các đối tượng Item là kiểu chuỗi, ta truyền vào một chuỗi để
xóa. Nếu có nhiều giá trị giống nhau trong danh sách, chỉ có mục chọn đầu tiên
bị xóa.


<b> RemoveAt: Xóa một item tại vị trí index ra khỏi danh sách: </b>
Items.RemoveAt(<index>);


<b> Clear: Xóa tất cả những Item có trong danh sách: Items.Clear(). </b>
<b> Contains(value): kiểm tra phần tử có trong danh sách không. </b>
<b>* Một số sự kiện quan trọng tác động đến điều khiển ListBox: </b>


SelectedIndexChanged



Thay đổi vị trí phần tử
đang chọn qua thuộc
tính SelectedIndex hoặc
SelectedItem


SelectedValueChanged Thay đổi giá trị phần tử
đang chọn


Focus Điều khiển nhận được
tập trung


LosFocus Điểm làm việc được rời
khỏi điều khiển


<b>* Ví dụ: Thiết kế Form cho yêu cầu mượn sách </b>


</div>
<span class='text_page_counter'>(83)</span><div class='page_container' data-page=83>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU


 <b>Bước 2: Nhấn double vào Program.cs góc phải màn hình như dưới: </b>




Sau đó sẽ hiển thị ra tab mới, khi đó bạn có thể chạy chương trình


</div>
<span class='text_page_counter'>(84)</span><div class='page_container' data-page=84>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
<b>Thêm </b>


<b> Chọn </b>


</div>
<span class='text_page_counter'>(85)</span><div class='page_container' data-page=85>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU



<b> </b>
<b> Hủy </b>


</div>
<span class='text_page_counter'>(86)</span><div class='page_container' data-page=86>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
<b> Hủy nhiều </b>


</div>
<span class='text_page_counter'>(87)</span><div class='page_container' data-page=87>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU


</div>
<span class='text_page_counter'>(88)</span><div class='page_container' data-page=88>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
<b>CheckListBox </b>


Điều khiển CheckedListBox cung cấp cho bạn tất cả khả năng của hộp danh sách và
cũng cho phép bạn hiển thị check mark bên cạnh các mục trong hộp danh sách.


Người dùng có thể đặt dấu kiểm theo một hoặc nhiều mục và các mục đã kiểm tra có
thể được điều hướng bằng CheckedListBox.CheckedItemCollection và
CheckedListBox.CheckedIndexCollection .


Checkedlistbox add items


public int Add (object item, bool isChecked);


Bạn có thể thêm từng mục vào danh sách bằng phương pháp Thêm . Đối tượng
CheckedListBox hỗ trợ ba trạng thái thông qua kiểu liệt kê CheckState: Đã kiểm tra,
Không xác định và Không kiểm tra.


checkedListBox1.Items.Add("Sunday", CheckState.Checked);
checkedListBox1.Items.Add("Monday", CheckState.Unchecked);
checkedListBox1.Items.Add("Tuesday", CheckState.Indeterminate);



Nếu bạn muốn thêm đối tượng vào danh sách tại thời điểm chạy, hãy gán một mảng
tham chiếu đối tượng bằng phương thức AddRange . Sau đó, danh sách sẽ hiển thị giá
trị chuỗi mặc định cho mỗi đối tượng.


</div>
<span class='text_page_counter'>(89)</span><div class='page_container' data-page=89>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU


Theo mặc định, các mục trong hộp kiểm đã được bỏ chọn .
Kiểm tra tất cả các mục trong Hộp kiểm tra


Nếu bạn muốn kiểm tra một mục trong Checkedlistbox, bạn cần gọi SetItemChecked
với mục có liên quan.


public void SetItemChecked (int index, bool value);
Thông số


index (Int32) - Chỉ mục của mục để đặt trạng thái kiểm tra.
value (Boolean) - true để đặt mục là đã chọn; ngược lại, sai.


Nếu bạn muốn đặt tất cả các mục trong CheckedListBox thành được chọn, hãy thay
đổi giá trị của phương thức SetItemChecked thành true.


string[] days = new[] { "Sunday", "Monday", "Tuesday" };
checkedListBox1.Items.AddRange(days);


for (int i = 0; i < checkedListBox1.Items.Count; i++)
{


</div>
<span class='text_page_counter'>(90)</span><div class='page_container' data-page=90>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
Bỏ chọn tất cả các mục trong Hộp kiểm tra



Nếu bạn muốn đặt tất cả các mục trong CheckedListBox thành bỏ chọn, hãy thay đổi
giá trị của phương thức SetItemChecked thành false.


checkedListBox1.Items.Add("Sunday", CheckState.Checked);
checkedListBox1.Items.Add("Monday", CheckState.Checked);
checkedListBox1.Items.Add("Tuesday", CheckState.Checked);
for (int i = 0; i < checkedListBox1.Items.Count; i++)


{


checkedListBox1.SetItemChecked(i, false);
}


CheckedListBox DataSource


Ví dụ sau cho thấy cách liên kết một Nguồn dữ liệu với CheckedListBox


DataTable dt = new DataTable();


</div>
<span class='text_page_counter'>(91)</span><div class='page_container' data-page=91>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
DataRow dr = dt.NewRow();


dr[0] = "Item_1";
dt.Rows.Add(dr);


this.checkedListBox1.DataSource = dt;


this.checkedListBox1.DisplayMember = "StringType";



Làm thế nào để nhận giá trị của mục đã kiểm tra từ CheckedListBox?


public System.Windows.Forms.CheckedListBox.ObjectCollection Items { get; }


Ví dụ sau đây sử dụng thuộc tính Items để lấy CheckedListBox.ObjectCollection để
lấy chỉ mục của một mục bằng phương thức ListBox.ObjectCollection.IndexOf.


private void button1_Click_1(object sender, EventArgs e)
{


foreach (int indexChecked in checkedListBox1.CheckedIndices)
{


// The indexChecked variable contains the index of the item.


MessageBox.Show("Index: " + indexChecked.ToString() + ", is checked.
Checked state is:" +


checkedListBox1.GetItemCheckState(indexChecked).ToString() + ".");
}


</div>
<span class='text_page_counter'>(92)</span><div class='page_container' data-page=92>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU
<b>4.2. DataGrid </b>


1. Control DataGridView


Là control được tổ chức dưới dạng bảng với các cột dọc (column) và hàng ngang
(row), trên đầu mỗi cột có tên cột. DataGridView hữu ích trong trường hợp xuất dữ
liệu có cấu trúc mảng 2 chiều, bảng dữ liệu, lưu trữ thống kê, database…



2. Xử lý cột (Column) trong DataGridView


Khi vừa khởi tạo từ ToolBox, DataGridView là bảng trống khơng có dịng và cột,
trước tiên ta cần phải tạo cột, sau đó mới có thể thêm dữ liệu vào theo từng hàng. Đầu
tiên ta sẽ tìm hiểu cách xử lý cột trong giao diện kéo thả của Visual Studio và sau đó là
xử lý trên Code. Đầu tiên ta nhấm vào mũi tên nhỏ ở góc phải phía trên của control để
xuất hiện bảng DataGridView Task, tại đây ta có thể thêm cột và thiết lập tùy chỉnh
cho các cột đó. Thêm cột tại Add Column và chỉnh sửa cột tại Edit Column. Các
checkbox bên dưới thiết lập cho phép (hoặc khơng) thêm, bớt, chỉnh sửa, xóa dữ liệu
trên DataGridView trong quá trình chạy ứng dụng.


Nhìn vào bảng Edit Column bên dưới ta thấy trình quản lý các column, tại đây ta có
thể thay đổi tên, text hiển thị đầu dòng và một số tùy chỉnh layout tại nhóm chức năng
Layout


Control DataGridView trong Lập trình Windows Form C#
3. Xử lý cột trong Code.


Bên dưới là cách thêm cột cho DataGridView. Trong ví dụ ta cần thêm 3 cột nên lần
lượt tạo 3 đối tượng DataGridViewTextBoxColumn và thứ tự thiết lập thuộc tính cho
mỗi cột và cuối cùng thông qua phương thức AddRange để Add các cột vào
DataGridView. Trong ví dụ trên ta thấy cịn có 1 cột nhỏ bên trái DataGridView, để ẩn
cột này ta thiết lập giá trị False cho thuộc tính RowHeaderVisible.


Control DataGridView trong Lập trình Windows Form C#
4. Thêm dữ liệu cho DataGridView


Thông qua phương thức Rows.Add() ta có thể dễ dàng thêm dữ liệu cho
DataGridView. Ta thấy DataGridView có 3 cột nên đối số của phương thức
Rows.Add() cần có 3 chuỗi, nếu ít hơn thì những vị trí sau sẽ bị chừa trống.



Control DataGridView trong Lập trình Windows Form C#
5. Truy xuất dữ liệu trong DataGridView


DataGridView tổ chức dữ liệu giống như 1 mảng 2 chiều thơng thường, ta có thể thiết
lập và truy xuất dữ liệu dễ dàng thông qua chỉ số hàng và cột. Bên dưới ta tiến hành
lấy dữ liệu trong DataGridView thông qua các chỉ số hàng, cột đưa vào ở các TextBox.
Lưu ý: dữ liệu trong các Cell (ô) lưu trữ dưới kiểu string. Việc gán dữ liệu vào bảng
cũng tiến hành tương tự.


Control DataGridView trong Lập trình Windows Form C#
6. Event Cell Click


</div>
<span class='text_page_counter'>(93)</span><div class='page_container' data-page=93>

CHƯƠNG 4. CÁC ĐIỀU KHIỂN LIÊN KẾT DỮ LIỆU


</div>
<span class='text_page_counter'>(94)</span><div class='page_container' data-page=94>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG

<b>CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG </b>


<b>5.1. Xây dựng ứng dụng với mơ hình 3-layer </b>


C# – Mơ hình 3 lớp đơn giản


Đối với lập trình hiện đại, mọi thứ đều đi nhiều lớp, tương tự như C#, cũng có cả mơ
hình 3 lớp để chúng ta thực thi áp dụng.


Ở C# chúng ta gọi là mô hình 3 lớp aka 3 Layers. Nó khá là nổi tiếng với sinh viên VN
đang học C# (một số trường sẽ là Lập trình .NET, lập trình C#, lập trình ứng dụng)
Cấu tạo của C# – Mơ hình 3 lớp đơn giản:


Gồm 3 lớp, đó là:



GUI Layer: Lớp này là lớp hiển thị giao diện và các chức năng để người dùng cuối
sử dụng.


Business (BUS) Layer: Đây là lớp nhận các yêu cầu từ lớp GUI và truy xuất lên lớp
Data để lấy thông tin và trả về GUI.


Data Access Layer: Lớp này là lớp để truy xuất với CSDL, chỉ duy nhất lớp này
được làm việc với database.


(Ko cần thiết) DTO Layer: Lớp này chỉ là phụ thôi, đây là lớp định nghĩa các table
trong database của bạn, định nghĩa cột của nó cũng như để ta gán data khi query lấy dữ
liệu. Các bạn có thể hiểu nơm na là 1 dạng cơ bản ORM (Object Relation Mapping).
Đây là cách hoạt động của mơ hình 3 lớp:


Nhìn sơ qua thì nó khá là giống MVC bên web nhỉ? Business như là Controller :D,
GUI là View và Data Access là Model.


</div>
<span class='text_page_counter'>(95)</span><div class='page_container' data-page=95>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG


Phân loại rõ ràng các lớp có các nhiệm vụ khác nhau. Từ đó ta có thể quản lý và
maintain project tốt hơn.


Dễ dàng phân loại các hành động tại Business.


Dễ dàng phân loại các hàm truy xuất tại Database, phân loại hàm theo table,…
Ứng dụng được cho các project lớn ở bên ngoài.




Lưu ý khi xây dựng mơ hình 3 lớp:


Cần một solution riêng cho project.


Cần 3 project khác nhau để làm nên 3 lớp, tên Project đặt như sau:
Lớp GUI: GUI_* (VD: GUI_QuanLy)


Lớp Business: BUS_* (VD: BUS_QuanLy)
Lớp Data Access: DAL_* (VD: DAL_QuanLy)
Lớp DTO: DTO_* (VD: DTO_QuanLy)


Bên trong 3 lớp như trên các file đặt cần có các tiền tố như sau:
Ví dụ mình có một table tên là ThanhVien


Lớp GUI: GUI_* (VD: GUI_ThanhVien)
Lớp Business: BUS_* (VD: GUI_ThanhVien)
Lớp Data Access: DAL_* (VD: GUI_ThanhVien)
Lớp DTO: DTO_* (VD: DTO_ThanhVien)


C# – Mơ hình 3 lớp đơn giản: Liên kết 3 lớp
GUI liên kết tới dc Business Layer và DTO.


Business Layer liên kết tới được Data Access và DTO.
Data Access chỉ liên kết tới DTO


<b>5.1.1. Tổ chức cây thư mục </b>
1. Presentation Layer (GUI):


Có hai thành phần chính sau đây với những tác vụ cụ thể :


UI Components : gồm các thành phần tạo nên giao diện của ứng dụng (GUI). Chúng
chịu trách nhiệm thu nhận và hiển thị dữ liệu cho người dùng… Ví dụ : textbox,


button, combobox, …


</div>
<span class='text_page_counter'>(96)</span><div class='page_container' data-page=96>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG
1.Hiển thị màn hình tra cứu ID


2.Hiển thị màn hình thơng tin chi tiết khách hàng tương ứng
3.Hiển thị màn hình liên lạc với khách hàng.


2. Bussiness Layer (BLL) :


Lớp này gồm 4 thành phần:


Service Interface : là thành phần giao diện lập trình mà lớp này cung cấp cho lớp
Presentation sử dụng.


Bussiness Workflows : chịu trách nhiệm xác định và điều phối các quy trình nghiệp
vụ gồm nhiều bước và kéo dài. Những quy trình này phải được sắp xếp và thực hiện
theo một thứ tự chính xác.


Ví dụ : Thực hiện mua một đơn hàng trên tiki qua nhiều bước : kiểm tra gói hàng
cịn khơng?, tính tổng chi phí, cho phép giao dịch và sắp xếp việc giao hàng.


Bussiness Components : chịu trách nhiệm kiểm tra các quy tắc nghiệp vụ, ràng buộc
logic và thực hiện các công việc . Các thành phần này cũng thực hiện các dịch vụ mà
Service Interface cung cấp và Business Workflows sẽ sử dụng nó.


Ví dụ : Tiếp tục ví dụ ở trên. Bạn sẽ cần một Bussiness Component để kiểm tra gói
hàng có khả dụng khơng ? hay một component để tính tổng chi phí,…


Bussiness Entities : thường được sử dụng như Data Transfer Objects ( DTO ) . Bạn


có thể sử dụng để truyền dữ liệu giữa các lớp (Presentation và Data Layer). Chúng
thường là cấu trúc dữ liệu ( DataSets, XML,… ) hay các lớp đối tượng đã được tùy
chỉnh.


</div>
<span class='text_page_counter'>(97)</span><div class='page_container' data-page=97>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG


Data Access Logic Components : chịu trách nhiệm chính lưu trữ và truy xuất dữ liệu
từ các nguồn dữ liệu (Data Sources) như XML, file system,… Hơn nữa còn tạo thuận
lợi cho việc dễ cấu hình và bảo trì.


Service Agents : giúp bạn gọi và tương tác với các dịch vụ từ bên ngoài một cách
dễ dàng và đơn giản.


<b>5.1.2. Mơ hình đa tầng </b>
N-Tier Architecture?


Kiến trúc N-tier còn được gọi là multi-tier architecture, một phương pháp kiến trúc
ứng dụng trong phát triển phần mềm. Nó thích hợp cho việc xây dựng các ứng dụng
lớn, đặc biệt là các ứng dụng doanh nghiệp, các ứng dụng địi hỏi tính scalability,
security, fault tolerance, reusability và maintainability.


Gọi là N-tier điều đó có nghĩa kiến trúc này có thể có 1, 2, 3 hoặc hơn số các layer phụ
thuộc vào cách phân chia kiến trúc hệ thống. Tuy nhiên 3-Tier vẫn là mẫu phổ biến
nhất và được định nghĩa cụ thể về trách nhiệm từng tier như sau:


Tầng Presentation: Chính là Giao diện người dùng, đây chính là phần mềm ứng dụng
mà người dùng sẽ thấy và tương tác (Có thể là Website hoặc Mobile App, hoặc
Window app). Khi người dùng nhập thông tin họ cần. Hành động người dùng được xử
lí đi qua các tầng Logic, tầng Data.



</div>
<span class='text_page_counter'>(98)</span><div class='page_container' data-page=98>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG


Tầng Data: Tầng Data là nơi lưu trữ tất cả dữ liệu trong ứng dụng, tại tầng này bạn
thực hiện các phương thức lưu trữ dữ liệu vào DB, triển khai các giải pháp bảo mật,
transaction cần thiết.


<b>5.1.3. Xây dựng lớp xử lý lưu trữ </b>


Tại sao mình lại xây dựng Data Access trước? Đơn giản là đây là lớp mà ta xử lý bên
database, làm trước thì design GUI xong chỉ việc bỏ vào sử dụng thôi


Điều quan trọng đầu tiên, chúng ta cần tạo class DBConnect.cs với nội dung như sau:
using System.Data.SqlClient;


namespace DAL_QuanLy
{


public class DBConnect
{


protected SqlConnection _conn = new SqlConnection("Data
Source=ADMINISTRATOR\SQLEXPRESS;Initial Catalog=ThanhVien;Integrated
Security=True");


}
}
Copy


Chúng ta sẽ tạo SqlConnection và khởi tạo luôn, sau này các class DAL chúng ta chỉ
cần kế thừa class DBConnect là có thể sử dụng _conn thoải mái ko cần khởi tạo lại.


Các bạn nhớ sửa lại connection string cho chuẩn bên máy của các bạn nhé. Ở đây vì
bài tập đơn giản nên ta chịu khó hard-code vậy :D. Chúng ta có nhiều cách khác nhau
để tránh hard-code nhưng mình sẽ nói sau ở các bài khác.


Mình sẽ tạo file DAL_ThanhVien.cs (Class file)


Ở đây mình sẽ làm sẵn ln 4 methods là: Lấy tất cả, Thêm, Xóa, Sửa nhé
DAL_ThanhVien.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using DTO_QuanLy;
namespace DAL_QuanLy
{


public class DAL_ThanhVien : DBConnect
{


</div>
<span class='text_page_counter'>(99)</span><div class='page_container' data-page=99>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG
/// Get toàn bộ thành viên


/// </summary>


/// <returns></returns>


public DataTable getThanhVien()
{



SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM
THANHVIEN", _conn);


DataTable dtThanhvien = new DataTable();
da.Fill(dtThanhvien);


return dtThanhvien;
}


/// <summary>
/// Thêm thành viên
/// </summary>


/// <param name="tv"></param>
/// <returns></returns>


public bool themThanhVien(DTO_ThanhVien tv)
{


try
{


// Ket noi
_conn.Open();


// Query string - vì mình để TV_ID là identity (giá trị tự tăng dần) nên ko
cần fải insert ID


string SQL = string.Format("INSERT INTO THANHVIEN(TV_NAME,


TV_PHONE, TV_EMAIL) VALUES ('{0}', '{1}', '{2}')", tv.THANHVIEN_NAME,
tv.THANHVIEN_PHONE, tv.THANHVIEN_EMAIL);


// Command (mặc định command type = text nên chúng ta khỏi fải làm gì
nhiều).


SqlCommand cmd = new SqlCommand(SQL, _conn);
// Query và kiểm tra


if (cmd.ExecuteNonQuery() > 0)
return true;


}


</div>
<span class='text_page_counter'>(100)</span><div class='page_container' data-page=100>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG
}


finally
{


// Dong ket noi
_conn.Close();
}


return false;
}


/// <summary>
/// Sửa thành viên
/// </summary>



/// <param name="tv"></param>
/// <returns></returns>


public bool suaThanhVien(DTO_ThanhVien tv)
{


try
{


// Ket noi
_conn.Open();
// Query string


string SQL = string.Format("UPDATE THANHVIEN SET TV_NAME =
'{0}', TV_PHONE = '{1}', TV_EMAIL = '{2}' WHERE TV_ID = {3}",
tv.THANHVIEN_NAME, tv.THANHVIEN_PHONE, tv.THANHVIEN_EMAIL,
tv.THANHVIEN_ID);


// Command (mặc định command type = text nên chúng ta khỏi fải làm gì
nhiều).


SqlCommand cmd = new SqlCommand(SQL, _conn);
// Query và kiểm tra


if (cmd.ExecuteNonQuery() > 0)
return true;


}



catch (Exception e)
{


</div>
<span class='text_page_counter'>(101)</span><div class='page_container' data-page=101>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG
{


// Dong ket noi
_conn.Close();
}


return false;
}


/// <summary>
/// Xóa thành viên
/// </summary>


/// <param name="tv"></param>
/// <returns></returns>


public bool xoaThanhVien(int TV_ID)
{


try
{


// Ket noi
_conn.Open();


// Query string - vì xóa chỉ cần ID nên chúng ta ko cần 1 DTO, ID là đủ


string SQL = string.Format("DELETE FROM THANHVIEN WHERE
TV_ID = {0})", TV_ID);


// Command (mặc định command type = text nên chúng ta khỏi fải làm gì
nhiều).


SqlCommand cmd = new SqlCommand(SQL, _conn);
// Query và kiểm tra


if (cmd.ExecuteNonQuery() > 0)
return true;


}


catch (Exception e)
{


}
finally
{


</div>
<span class='text_page_counter'>(102)</span><div class='page_container' data-page=102>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG


return false;
}


}
}


<b>5.1.4. Xây dựng các lớp xử lý nghiệp vụ </b>



Bước này là bước xử lý business logic (Business layer).


<b>Ở bước này, ta có thể lấy dữ liệu từ DAL về, xử lý ABC XYZ gì đó rồi trả về lại cho </b>
<b>GUI sử dụng. Hoặc khi update dữ liệu trên DB, GUI gửi data lên BUS và rồi ta xử lý </b>
ABC XYZ gì đó cho data của chúng ta, rồi mới insert/update/delete chẳng hạn,…
<b>Vì app mình build là app đơn giản, nên mình chỉ cần gọi lên DAL và trả về tương ứng </b>
cho GUI xài thui


<b>Mình sẽ tạo BUS_ThanhVien.cs (Class file): </b>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using DAL_QuanLy;
using DTO_QuanLy;
namespace BUS_QuanLy
{


public class BUS_ThanhVien
{


DAL_ThanhVien dalThanhVien = new DAL_ThanhVien();


public DataTable getThanhVien()
{


return dalThanhVien.getThanhVien();
}



public bool themThanhVien(DTO_ThanhVien tv)
{


</div>
<span class='text_page_counter'>(103)</span><div class='page_container' data-page=103>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG


public bool suaThanhVien(DTO_ThanhVien tv)
{


return dalThanhVien.suaThanhVien(tv);
}


public bool xoaThanhVien(int TV_ID)
{


return dalThanhVien.xoaThanhVien(TV_ID);
}


}
}


Chỉ đơn giản là gọi hàm và trả về thôi


</div>
<span class='text_page_counter'>(104)</span><div class='page_container' data-page=104>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;


using System.Text;
using System.Windows.Forms;
using DTO_QuanLy;
using BUS_QuanLy;
namespace GUI_QuanLy
{


public partial class GUI_ThanhVien : Form
{


BUS_ThanhVien busTV = new BUS_ThanhVien();


public GUI_ThanhVien()
{


InitializeComponent();
}


private void btnExit_Click(object sender, EventArgs e)
{


Application.Exit();
}


private void btnAdd_Click(object sender, EventArgs e)
{


if (txtEmail.Text != "" && txtName.Text != "" && txtSDT.Text != "")
{



</div>
<span class='text_page_counter'>(105)</span><div class='page_container' data-page=105>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG


DTO_ThanhVien tv = new DTO_ThanhVien(0, txtName.Text, txtSDT.Text,
txtEmail.Text); // Vì ID tự tăng nên để ID số gì cũng dc


// Them


if (busTV.themThanhVien(tv))
{


MessageBox.Show("Thêm thành công");


dgvTV.DataSource = busTV.getThanhVien(); // refresh datagridview
}


else
{


MessageBox.Show("Thêm ko thành công");
}


}
else
{


MessageBox.Show("Xin hãy nhập đầy đủ");
}


}



private void GUI_ThanhVien_Load(object sender, EventArgs e)
{


dgvTV.DataSource = busTV.getThanhVien(); // get thanh vien
}


private void btnEdit_Click(object sender, EventArgs e)
{


// Kiểm tra nếu có chọn table rồi
if (dgvTV.SelectedRows.Count > 0)
{


</div>
<span class='text_page_counter'>(106)</span><div class='page_container' data-page=106>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG
// Lấy row hiện tại


DataGridViewRow row = dgvTV.SelectedRows[0];
int ID = Convert.ToInt16(row.Cells[0].Value.ToString());


// Tạo DTo


DTO_ThanhVien tv = new DTO_ThanhVien(ID, txtName.Text,
txtSDT.Text, txtEmail.Text); // Vì ID tự tăng nên để ID số gì cũng dc


// Sửa


if (busTV.suaThanhVien(tv))
{


MessageBox.Show("Sửa thành công");



dgvTV.DataSource = busTV.getThanhVien(); // refresh datagridview
}


else
{


MessageBox.Show("Sửa ko thành công");
}


}
else
{


MessageBox.Show("Xin hãy nhập đầy đủ");
}


}
else
{


MessageBox.Show("Hãy chọn thành viên muốn sửa");
}


}


</div>
<span class='text_page_counter'>(107)</span><div class='page_container' data-page=107>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG
// Lấy row hiện tại


DataGridViewRow row = dgvTV.SelectedRows[0];



// Chuyển giá trị lên form


txtName.Text = row.Cells[1].Value.ToString();
txtSDT.Text = row.Cells[2].Value.ToString();
txtEmail.Text = row.Cells[3].Value.ToString();
}


private void btnDelete_Click(object sender, EventArgs e)
{


// Kiểm tra nếu có chọn table rồi
if (dgvTV.SelectedRows.Count > 0)
{


// Lấy row hiện tại


DataGridViewRow row = dgvTV.SelectedRows[0];
int ID = Convert.ToInt16(row.Cells[0].Value.ToString());


// Xóa


if (busTV.xoaThanhVien(ID))
{


MessageBox.Show("Xóa thành công");


dgvTV.DataSource = busTV.getThanhVien(); // refresh datagridview
}



else
{


MessageBox.Show("Xóa ko thành cơng");
}


</div>
<span class='text_page_counter'>(108)</span><div class='page_container' data-page=108>

CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MƠ HÌNH ĐA TẦNG
{


MessageBox.Show("Hãy chọn thành viên muốn xóa");
}


</div>
<span class='text_page_counter'>(109)</span><div class='page_container' data-page=109>

CHƯƠNG 6. CRYSTAL REPORT

<b>CHƯƠNG 6. CRYSTAL REPORT </b>



<b>6.1 Crystal report </b>


- .NET cung cấp CrystalReport như một phần của Project, chúng ta có thể thêm báo
cáo (report) bằng cách chọn Project – Add New Item – CrystalReport.


- CrystalReport cung cấp nhiều hình dạng cho phép hiển thị dữ liệu một cách trực quan
theo các mẫu được thiết kế sẵn


<b>6.1.1. Tạo mới report </b>


Bước 1: Từ một Project có sẵn, click phải chọn Add – New Item – chọn Crystal Report


</div>
<span class='text_page_counter'>(110)</span><div class='page_container' data-page=110>

CHƯƠNG 6. CRYSTAL REPORT


</div>
<span class='text_page_counter'>(111)</span><div class='page_container' data-page=111>

CHƯƠNG 6. CRYSTAL REPORT



</div>
<span class='text_page_counter'>(112)</span><div class='page_container' data-page=112>

CHƯƠNG 6. CRYSTAL REPORT


Bước 5: Hoàn tất và chỉnh sửa báo cáo


<b>6.1.2. Sử dụng crystal report để hiển thị report </b>


- Sau khi thiết kế report thành công, chúng ta có thể tiếp tục thiết kế các report với
nhiều hình thức khác nhau. Tuy nhiên khi làm việc với C#, điều chúng ta quan tâm là
làm thế nào để tương tác với các report đã thiết kế với dữ liệu có chọn lọc, hình thức
chọn lọc từ CSDL nguồn.


</div>
<span class='text_page_counter'>(113)</span><div class='page_container' data-page=113>

CHƯƠNG 6. CRYSTAL REPORT


</div>
<span class='text_page_counter'>(114)</span><div class='page_container' data-page=114>

CHƯƠNG 6. CRYSTAL REPORT
<b>6.1.4. Tạo nguồn dữ liệu cho report từ nguồn CSDL </b>


<b>6.1.5. Lọc dữ liệu trên report </b>


crystalreportviewer.SelectionFomula = "{filed cần lọc} = " + {Điều kiện};
ví dụ:


DataSet _ds = new DataSet();


string _strConnection = "server=.;database=Electronic;User Id
=sa;Password=sa;";


System.Data.SqlClient.SqlConnection _sqlCon = new
System.Data.SqlClient.SqlConnection(_strConnection);



System.Data.SqlClient.SqlCommand _sqlCom = new
System.Data.SqlClient.SqlCommand();


_sqlCom.CommandText = "SELECT * FROM [tbl_DanhMucSanPham]";
_sqlCom.Connection = _sqlCon;


System.Data.SqlClient.SqlDataAdapter _sqlAdater = new
System.Data.SqlClient.SqlDataAdapter(_sqlCom);


_sqlAdater.Fill(_ds);
_sqlAdater.Dispose();


CrystalReport7 _rpt7 = new CrystalReport7();
crystalReportViewer1.ReportSource = _rpt7;


</div>
<span class='text_page_counter'>(115)</span><div class='page_container' data-page=115>

CHƯƠNG 6. CRYSTAL REPORT
<b>6.1.6. Truyền tham số cho report </b>


Có tham số:


</div>
<span class='text_page_counter'>(116)</span><div class='page_container' data-page=116>

CHƯƠNG 6. CRYSTAL REPORT


<b>6.1.8. Xuất report ra tập tin </b>


Crystal Report cho phép xuất dữ liệu từ báo cáo ra các định dạng khác như: Excel,
Word, PDF, HTML, Text v.v…


</div>
<span class='text_page_counter'>(117)</span><div class='page_container' data-page=117></div>
<span class='text_page_counter'>(118)</span><div class='page_container' data-page=118></div>
<span class='text_page_counter'>(119)</span><div class='page_container' data-page=119>

CHƯƠNG 6. CRYSTAL REPORT
<b>6.1.9. Đóng gói project </b>



Sau khi chúng ta xây dựng được một ứng dụng, để chạy được ứng dụng này trên một máy tính
khác, hoặc phân phối ứng dụng này đến nhiều người sử dụng khác, chúng ta cần phải đóng
gói project thành một chương trình cài đặt (Setup hoặc Install).


Bước 1: Tạo Project mới loại Setup and Deployment – Visual Studio Installer:


</div>
<span class='text_page_counter'>(120)</span><div class='page_container' data-page=120>

CHƯƠNG 6. CRYSTAL REPORT


</div>
<span class='text_page_counter'>(121)</span><div class='page_container' data-page=121>

CHƯƠNG 6. CRYSTAL REPORT
Bước 4: Bấm Next:


</div>
<span class='text_page_counter'>(122)</span><div class='page_container' data-page=122>

CHƯƠNG 6. CRYSTAL REPORT


</div>
<span class='text_page_counter'>(123)</span><div class='page_container' data-page=123>

<b>TÀI LIỆU THAM KHẢO </b>


<b>TT </b> <b>Tên tác giả </b> <b>Tên sách – giáo trình </b> <b>NXB </b> <b>Năm XB </b>


1 Phạm Hữu Khang C# 2005 – Lập trình cơ sở dữ
liệu – Tập 4 – Quyển 1


Lao động
xã hội


2009


2 Pham Hữu Khang C# 2005 0 Lập trình cơ sở dữ
liệu Report – Tập 4 – Quyển 2


Lao động
xã hội



2009

<b>GIÁO TRÌNH </b>



</div>

<!--links-->
Giáo trình máy xây dựng
  • 88
  • 4
  • 47
  • ×