You are on page 1of 202

MỤC LỤC

CHƯƠNG 1. 7
LÀM QUEN VỚI VISUAL STUDIO 2010 7
1. Giới thiệu Visual Studio.NET 2010 7
1.1. Tình hình trước khi Visual Studio.NET ra đời 7
1.2. Sự ra đời của Visual Studio.NET 7
1.3. Tổng quan về Visual Studio.NET 8
2. Khởi động Visual C# 2010 và giao diện 9
CHƯƠNG 2. 18
VIẾT CHƯƠNG TRÌNH ĐẦU TIÊN 18
1. Đề bài 18
3. Mở đồ án mới 18
4. Thiết kế giao diện 18
4.1. Đặt tên và tiêu đề cho form 18
4.2. Thêm điều khiển hộp văn bản Textbox 19
4.3. Thêm điều khiển nút lệnh Button 19
5. Viết code 20
5.1. Viết code cho nút lệnh btnDisplay 20
5.2. Viết code cho nút lệnh btnClear 22
5.3. Viết code cho nút lệnh btnExit 22
6. Lưu đồ án 22
7. Các tệp tin của đồ án 22
8. Chạy chương trình 23
9. Dừng chương trình 23
10. Mở đồ án đã có 23
11. Thoát khỏi Visual C# 2010 23
CHƯƠNG 3. 24
DỮ LIỆU VÀ CẤU TRÚC ĐIỀU KHIỂN 24
1. Biến, hằng và các kiểu dữ liệu 24
1.1. Biến 24
1.2. Hằng 25
1.3. Các kiểu dữ liệu 25

Bài giảng Cơ sở lập trình 2 1


1.4. Hàm chuyển đổi giữa các kiểu dữ liệu 30
2. Hộp thoại thông báo – MessageBox 30
2.1. Khái niệm 30
2.2. Hộp thông báo MessageBox 30
2.3. Hàm thông báo MessageBox 32
3. Các cấu trúc điều khiển 32
3.1. Câu lệnh lựa chọn if 32
3.2. Câu lệnh lựa chọn Case 33
Bài tập 1. 34
3.3. Cấu trúc lặp for 38
3.4. Cấu trúc lặp while 38
3.5. Cấu trúc lặp do 39
3.6. Câu lệnh try…catch 40
4. Hàm 41
4.1. Hàm có một giá trị trả về 41
4.2. Hàm không có giá trị trả về 42
4.3. Cách gọi hàm 42
4.4. Ví dụ minh họa 43
5. Gỡ rối chương trình 44
CHƯƠNG 4. 45
TÌM HIỂU CÁC ĐIỀU KHIỂN CƠ BẢN 45
1. Tìm hiểu thuộc tính, phương thức và sự kiện 45
2. Mối quan hệ giữa thuộc tính, phương thức và sự kiện 45
3. Thuộc tính, phương thức, sự kiện của một số điều khiển cơ bản 46
3.1. Form 46
3.2. Hộp văn bản - TextBox 48
3.3. Nút lệnh – Button 50
3.4. Nhãn – Lable 51
3.5. Dòng mách nước - ToolTip 51
3.6. Bài tập 52
Bài tập 2. 52
Bài tập 3. 55

Bài giảng Cơ sở lập trình 2 2


Bài tập 4. 56
Bài tập 5. 57
4. Một số điều khiển cơ bản khác 59
4.1. Nhóm – GroupBox 59
4.2. Hộp đánh dấu – CheckBox 59
4.3. Nút tuỳ chọn – RadioButton 60
Bài tập 6. 61
Bài tập 7. 68
4.4. Hộp danh sách – ListBox 69
Bài tập 8. 72
Bài tập 9. 74
4.5. Hộp lựa chọn – ComboBox 76
Bài tập 10. 78
Bài tập 11. 79
Bài tập 12. 80
Bài tập 13. 81
4.6. Điều khiển CheckedListBox 82
Bài tập 14. 83
4.7. Điều khiển NumericUpDown 84
Bài tập 15. 85
4.8. Thanh cuộn HScrollBar và VScrollBar 87
Bài tập 16. 87
4.9. Điều khiển Timer 88
Bài tập 17. 89
Bài tập 18. 92
4.10. Điều khiển RichTextBox 93
4.11. Điều khiển Windows Media Player 93
Bài tập 19. 94
CHƯƠNG 5. 97
CÁC HỘP THOẠI THÔNG DỤNG 97
1. Hộp hội thoại Open File 97
Bài tập 20. 97

Bài giảng Cơ sở lập trình 2 3


2. Hộp thoại SaveFile và luồng FileStream 99
2.1. Hộp thoại SaveFile 99
2.2. Luồng FileStream 99
Bài tập 21. 100
3. Hộp thoại Color 101
Bài tập 22. 102
4. Hộp thoại Font 103
Bài tập 23. 103
Bài tập 24. 104
CHƯƠNG 6. 106
MENU VÀ ĐỒ ÁN NHIỀU BIỂU MẪU 106
1. Menu - MenuStrip 106
1.1. Thuộc tính 106
1.2. Sự kiện 107
Bài tập 25. 107
2. Popup menu - ContextMenuStrip 108
Bài tập 26. 108
3. Đồ án nhiều biểu mẫu 110
3.1. Bổ sung biểu mẫu 110
Bài tập 27. 111
3.2. Biểu mẫu khởi động 111
3.3. Gọi biểu mẫu 112
3.4. Đóng biểu mẫu 112
3.5. Xoá biểu mẫu 112
Bài tập 28. 113
Bài tập 29. 113
Bài tập 30. 115
CHƯƠNG 7. 118
LẬP TRÌNH CƠ SỞ DỮ LIỆU 118
1. Giới thiệu bài toán 118
2. Tạo cơ sở dữ liệu 118
2.1. Tạo bảng tblChatlieu 121

Bài giảng Cơ sở lập trình 2 4


2.2. Tạo bảng tblHang 122
2.3. Tạo bảng tblNhanvien122
2.4. Tạo bảng tblKhach 122
2.5. Tạo bảng tblHDBan 122
2.6. Tạo bảng tblChitietHDBan 123
2.7. Tạo quan hệ Relationship 123
2.8. Tạo kết nối cơ sở dữ liệu 124
3. Tạo thư mục chứa ảnh126
4. Xây dựng Form chính cho chương trình 126
4.1. Tạo giao diện Form chính 126
4.2. Viết mã lệnh Form chính 127
4.3. Tạo lớp – Class Functions 128
5. Xây dựng Form cập nhật danh mục Chất liệu 129
5.1. Tạo giao diện Form frmDMChatlieu 129
5.2. Viết mã lệnh Form frmDMChatlieu 130
6. Xây dựng Form cập nhật danh mục Nhân viên 137
6.1. Tạo giao diện Form frmDMNhanvien 137
6.2. Viết mã lệnh Form frmDMNhanvien 138
7. Xây dựng Form cập nhật danh mục Khách hàng 144
7.1. Tạo giao diện Form frmDMKhachhang 144
7.2. Viết mã lệnh Form frmDMKhachhang 145
8. Xây dựng Form cập nhật danh mục Hàng 149
8.1. Tạo giao diện Form frmDMHang 149
8.2. Viết mã lệnh Form frmDMHang 150
9. Xây dựng Form cập nhật Hóa đơn bán 158
9.1. Tham chiếu thư viện Microsoft.Office.Interop.Excel159
9.2. Tạo giao diện Form frmHoadonBan 159
9.3. Viết mã lệnh Form frmDMHoadonBan 159

Bài giảng Cơ sở lập trình 2 5


CHƯƠNG 1.
LÀM QUEN VỚI VISUAL STUDIO 2010

1. Giới thiệu Visual Studio.NET 2010

1.1. Tình hình trước khi Visual Studio.NET ra đời

Với sự phát triển liên tục và đa dạng của thế giới công nghệ thông tin ngày nay, các phần mềm, các
hệ điều hành, các môi trường phát triển và các ứng dụng liên tục ra đời. Tuy nhiên, đôi khi việc phát
triển không đồng nhất và nhất là do không tương thích về mặt lợi ích của các công ty phần mềm lớn
đã làm ảnh hưởng đến công việc của những kỹ sư xây dựng phần mềm.

Trong giới phát triển ứng dụng trên Internet ta có thể sử dụng các ngôn ngữ Java, PHP, ASP… Khi
Java mới được Sun Corporation giới thiệu nó đã có một sức mạnh đáng kể và hướng tới việc chạy
trên nhiều hệ điều hành khác nhau, độc lập với các bộ xử lý. Đặc biệt Java rất thích hợp cho việc
Bài giảng Cơ sở lập trình 2 6
viết các ứng dụng trên Internet. Tuy nhiên, Java lại có hạn chế về mặt tốc độ và trên thực tế vẫn
chưa thịnh hành.

Để làm giảm khả năng ảnh hưởng của Java, bên hãng Microsoft cũng cung cấp ngôn ngữ ASP -
chuyên dùng để viết các ứng dụng trên Web. Trong các trang ASP vừa chứa thẻ HTML vừa chứa
các đoạn script (VBScript, JavaScript). Trong quá trình xử lý một trang ASP, nếu là thẻ HTML thì
sẽ được gửi thẳng tới trình duyệt, còn nếu là các đoạn script thì sẽ được chuyển thành các dòng
HTML rồi gửi đi. Khi nhà lập trình muốn đóng gói và sử dụng lại một số chức năng nào đó, thì họ
dịch các đoạn chương trình thành ActiveX và đưa nó vào Web Server. Tuy nhiên, vì lý do bảo mật
nên các Admin của các trang Web thường rất dè dặt khi cài ActiveX lạ trên máy của họ, ngoài ra
việc tháo gỡ các phiên bản của ActiveX này cũng là công việc rất khó khăn.

Còn trong giới phát triển ứng dụng trên Windows ta có thể viết ứng dụng bằng Visual C++, Delphi,
Visual Basic… đây là một số công cụ phổ biến và mạnh. Trong đó Visual C++ là một ngôn ngữ rất
mạnh nhưng cũng rất khó sử dụng. Visual Basic thì đơn giản dễ học, dễ dùng nhất nên rất thông
dụng nhưng hạn chế là Visual Basic không phải ngôn ngữ hướng đối tượng và không hỗ trợ khả
năng phát triển thuật toán.

Tóm lại trong giới lập trình theo Microsoft thì việc lập trình trên desktop cho đến lập trình hệ phân
tán hay trên web là những mảng độc lập.

1.2. Sự ra đời của Visual Studio.NET

Đầu năm 1998, sau khi hoàn tất phiên bản Version 4 của Internet Information Server -IIS, đội ngũ
lập trình của Microsoft nhận thấy họ còn có rất nhiều sáng kiến để có thể kiện toàn IIS, và họ bắt
đầu xây dựng một kiến trúc mới trên nền tảng ý tưởng đó và đặt tên là Next Generation Windows
Services - NGWS. Tham vọng của họ là cung cấp một môi trường có thể dùng chung cho tất cả
ngôn ngữ lập trình trong bộ Visual Studio cũng như cho các ngôn ngữ lập trình của các công ty
khác.

Kết quả là năm 2001 Visual Studio.Net 2001 ra đời đánh dấu cho một môi trường lập trình trên
nền .NET Framework 1.0 tiên tiến mới.

Năm 2003, sau 2 năm .NET Framework nâng cấp thêm một bậc với phiên bản 1.1 với đặc điểm
ngoài các chương trình Windows truyền thống – là các tệp tin .exe giờ đây Windows còn tồn tại
những chương trình khác – những chương trình chạy trên nền .NET. Muốn chạy chương trình .NET
ta chỉ cần cài .NET Framework là đủ. Một điểm lý thú và cũng là điều mong đợi của tất cả lập trình
viên, từ phiên bản Windows 2003 .NET Framework được cài đặt như một phần mặc định của
Windows. Song song đó, môi trường phát triển Visual Studio .NET 2001 được nâng cấp thành
Visual Studio .NET 2003 cho phép viết và chạy các ứng dụng trên nền .NET Framework 1.1

Cuối năm 2005, Visual Studio 2005 với nền .NET Framework 2.0 mạnh mẽ và vượt trội hơn so với
nền .NET Framwork 1.1 trước đó. Ngay sau đó Microsoft công bố phiên bản Windows Vista, và
toàn bộ Windows là .NET, tất cả các hàm API lõi trong những phiên bản Windows trước đây đều đã
được thay thế bằng các hàm hay thư viện .NET. Microsoft đã viết lại hoàn toàn lõi API, không còn
một lớp API nào nữa.

Bài giảng Cơ sở lập trình 2 7


1.3. Tổng quan về Visual Studio.NET

Visual Studio.NET gồm 2 phần: Framework và Integrated Development Environment– IDE, cho
phép lập trình viên khi xây dựng các ứng dụng có thể lựa chọn sử dụng nhiều ngôn ngữ lập trình
khác nhau như Visual C#.NET, Visual Basic.NET… trong cùng một môi trường phát triển IDE
thống nhất trên kiến trúc .NET Framework.

Framework là thành phần quan trọng nhất, là cốt lõi và tinh hoa của môi trường .NET, Framework
giúp chúng ta biên dịch và thực thi các ứng dụng .NET (cấu trúc của Framework chúng ta sẽ tìm
hiểu ở các chương sau của giáo trình).

IDE cung cấp một môi trường phát triển trực quan, giúp các lập trình viên có thể dễ dàng và nhanh
chóng xây dựng giao diện cũng như viết mã lệnh cho 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ăn bản bất kỳ, ví dụ như Notepad để
viết mã lệnh và sử dụng command line để biên dịch và thực thi ứng dụng. Tuy nhiên việc này mất
rất nhiều thời gian, tốt nhất là chúng ta nên dùng IDE để phát triển các ứng dụng, và đó cũng là cách
dễ sử dụng nhất.

Ngoài ra trong Visual Studio.NET thì lập trình Winform và Webform là tương tự, ví dụ cả Visual
C#.NET lẫn Visual Basic.NET đều hỗ trợ khả năng lập trình trên Win và Web…

2. Khởi động Visual C# 2010 và giao diện

 Vào Start/Programs/Microsoft Visual Studio 2010/Microsoft Visual Studio 2010, xuất hiện cửa
sổ Start Page.

Bài giảng Cơ sở lập trình 2 8


Hình 1. Cửa sổ Start Page

+ New Project: Tạo đồ án mới.

+ Open Project: Mở các đồ án có sẵn.

+ Recent Projects: Danh sách các đồ án gần đây nhất.

 Kích chọn mục New Project hoặc vào File/New/Project hoặc bấm phím tắt Ctrl+Shift+N xuất
hiện cửa sổ New Project

Bài giảng Cơ sở lập trình 2 9


Hình 2. Cửa sổ New Project

 Chọn ngôn ngữ Visual C# và ứng dụng Windows.

 Đặt tên cho đồ án tại mục Name.

 Chọn đường dẫn lưu đồ án tại mục Location.

 Mục Create directory for solution cho phép tạo một thư mục tại Location chứa tất cả các tệp
phát sinh của đồ án (nếu không các tệp của đồ án sẽ được lưu tại Location).

Hình 3. Thư mục chứa đồ án

 Chọn OK để tạo một đồ án mới.

Bài giảng Cơ sở lập trình 2 10


Kết quả xuất hiện cửa sổ môi trường phát triển tích hợp IDE, với giao diện và các thành phần cơ bản
như sau:

Hình 4. Môi trường phát triển tích hợp IDE

 Title Bar: Thanh tiêu đề chứa tên đồ án.

 Menu Bar: Thanh Menu chứa đầy đủ các công cụ cần để phát triển, thực thi và cài đặt ứng
dụng…

 File: cho phép mở, thêm mới và lưu trữ đồ án…

 Edit: gồm các thao tác hỗ trợ việc soạn thảo mã lệnh như: copy, cắt, dán...

 View: cho phép hiển thị các công cụ hỗ trợ người dùng trong quá trình xây dựng đồ án như:

- Cửa sổ viết mã lệnh - Code


- Form thiết kế - Designer
- Hộp công cụ - Toolbox

Bài giảng Cơ sở lập trình 2 11


- Thanh công cụ - Toolbars
- Cửa sổ thuộc tính - Properties Window…
 Project: cho phép bổ sung các đối tượng khác nhau vào đồ án như: các form, các component,
các modul, các lớp…

 Built: cho phép biên dịch đồ án.

 Debug: cho phép chạy và gỡ rối chương trình.

 Data: cho phép thêm mới và hiển thị cơ sở dữ liệu của đồ án.

 Tools: cung cấp các công cụ cho phép kết nối tới các thiết bị ngoại vi như Pocket PC,
Smartphone… hoặc kết nối tới các hệ quản trị cơ sở dữ liệu cũng như kết nối tới máy chủ
server…

 Toolbar: thanh công cụ gồm một tập hợp các nút lệnh, mỗi nút lệnh chứa một biểu tượng icons
và có chức năng tương đương với chức năng của một mục lựa chọn trong thanh menu. Thanh công
cụ rất hữu ích và trực quan, giúp người dùng dễ dàng và nhanh chóng thực hiện một chức năng
mong muốn chỉ thông qua một cái kích chuột.

Visual C# 2010 có tới 39 thanh công cụ khác nhau như: Standard, Formatting, Debug, Build... Ví dụ
hình ảnh thanh công cụ Standard:

Hình 5. Thanh công cụ Standard

Để gọi các thanh công cụ ta vào View/Toolbars khi đó sẽ xuất hiện danh sách tất cả các thanh công
cụ. Muốn ẩn/hiện thanh công cụ nào ta kích chọn tại dòng chứa tên thanh công cụ đó.

 Toolbox: là hộp công cụ chứa các điều khiển – controls được đặt lên Form khi thiết kế giao diện
người dùng.

Để hiển thị hộp công cụ ta thực hiện một trong các cách sau:

 Vào View/Toolbox

 Bấm tổ hợp phím Ctrl+W+X

 Kích chuột tại biểu tượng Toolbox trên thanh công cụ Standard.

Bài giảng Cơ sở lập trình 2 12


Hình 6. Hộp công cụ Toolbox

Mặc định hộp công cụ được chia thành 11 tab khác nhau như: All Windows Forms, Common
Controls...

Ta có thể thêm mới, loại bỏ, đổi tên... các tab bằng cách kích chuột phải tại vị trí bất kỳ trên tab,
xuất hiện một menu ngữ cảnh cho phép lựa chọn các thao tác cần thực hiện.

Hình 7. Các chức năng làm việc với từng tab trong Toolbox

Bài giảng Cơ sở lập trình 2 13


Trong mỗi tab của hộp Toolbox chứa danh sách các loại điều khiển khác nhau, các điều khiển này
có thể thêm mới, loại bỏ, thay đổi vị trí… Kích chuột phải tại một điều khiển bất kỳ trên tab, xuất
hiện một menu ngữ cảnh cho phép lựa chọn các thao tác cần thực hiện.

Ví dụ để thêm mới một điều khiển vào trong tab Data, ta kích chuột phải tại vị trí bất kỳ trên tab
Data, chọn Choose Items...

Hình 8. Các chức năng làm việc với từng điều khiển trong tab

Kết quả sẽ xuất hiện cửa sổ Choose Toolbox Items, kích chọn các điều khiển mong muốn rồi bấm
OK để kết thúc.

Hình 9. Cửa sổ Choose Toolbox Items

Bài giảng Cơ sở lập trình 2 14


 Form Designer: cửa sổ thiết kế dùng để thiết kế giao diện cho chương trình, mỗi dự án có thể có
một hoặc nhiều Form.

Hình 10. Cửa số Form Designer

 Solution Explorer: cửa sổ giải pháp - đây là phần cửa sổ giúp ta quản lý tất cả các tài nguyên và
tập tin dự án.

Solution Explorer được tổ chức thành một cấu trúc cây bao gồm những mục khác nhau, như: danh
sách các Form của đồ án, danh sách các lớp Class, danh sách các tài nguyên cũng như danh sách cơ
sở dữ liệu…

Để hiển thị cửa sổ Solution Explorer ta thực hiện một trong các cách sau:

 Vào View/Solution Explorer

 Bấm tổ hợp phím Ctrl+W+S

 Kích chuột tại biểu tượng Solution Explorer trên thanh công cụ Standard

Hình 11. Cửa sổ Solution Explorer

Trong cửa sổ Solution Explorer có hai thành phần hay dùng là View Code và View Designer.
Bài giảng Cơ sở lập trình 2 15
View Code: có tác dụng hiển thị cửa sổ soạn thảo mã lệnh cho Form đang được chọn. Ngoài ra, để
hiển thị cửa sổ soạn thảo mã lệnh ta còn có một số cách khác như sau:

 Vào View/Code.

 Bấm phím tắt F7.

 Kích đúp chuột tại cửa sổ thiết kế của form.

Giao diện cửa sổ soạn thảo như sau:

Hình 12. Cửa sổ soạn thảo

View Designer: có tác dụng hiển thị cửa sổ thiết kế giao diện của Form đang được chọn. Ngoài ra,
để hiển thị cửa sổ thiết kế giao diện ta còn có một số cách khác như sau:

 Vào View/Designer

 Bấm phím tắt Shift+F7.

Bài giảng Cơ sở lập trình 2 16


 Properties Window: cửa sổ này liệt kê tất cả các thuộc tính, sự kiện của các điều khiển trong
form.

Muốn hiển thị thuộc tính của đối tượng nào ta kích chuột chọn đối tượng đó trong cửa sổ thiết kế
giao diện, hoặc chọn tên đối tượng trong danh sách thả xuống ở phần đầu của cửa sổ Properties.

Hình 13. Cửa sổ Properties

Mỗi thuộc tính có một giá trị mặc định, ta có thể thay đổi giá trị của các thuộc tính trực tiếp tại cửa
sổ Properties trong lúc thiết kế, hoặc thay đổi bằng mã lệnh trong lúc thi hành chương trình.

Để hiển thị cửa sổ Properties ta thực hiện theo một trong các cách sau:

 Vào View\Properties Window.

 Kích chọn biểu tượng Properties Window trên thanh công cụ Standard.

 Bấm phím tắt Ctrl+W+P

Bài giảng Cơ sở lập trình 2 17


CHƯƠNG 2.
VIẾT CHƯƠNG TRÌNH ĐẦU TIÊN

Một chương trình ứng dụng trong C# được thực hiện theo hai bước sau:

 Thiết kế giao diện.

 Viết mã lệnh cho chương trình.

1. Đề bài

Viết chương trình gồm 1 hộp văn bản Textbox và 3 nút lệnh Button: Display, Clear, Exit với các
yêu cầu sau:

 Kích chuột vào nút Display thì trong hộp văn bản xuất hiện dòng chữ: “Welcome to Visual
C# 2010”.

 Kích chuột vào nút Clear thì nội dung trong hộp văn bản mất đi.

 Kích chuột vào nút Exit để thoát khỏi chương trình quay lại cửa sổ soạn thảo.

Hình 14. Giao diện chương trình đầu tiên

3. Mở đồ án mới

Mở Microsoft Visual Studio 2010, chọn File/New/Project để khởi động một đồ án mới.

Chọn ngôn ngữ Visual C# và ứng dụng Windows, đặt tên cho đồ án tại mục Name là Welcome rồi
chọn OK.

4. Thiết kế giao diện

4.1. Đặt tên và tiêu đề cho form

Kích chuột vào vị trí bất kỳ trên Form, trong cửa sổ Properties sửa các thuộc tính:

Bài giảng Cơ sở lập trình 2 18


 Name: frmWelcome

 Text: The first program

Trong cửa sổ Solution Explorer kích chuột tại Form1.cs, trong cửa sổ Properties sửa thuộc tính File
Name là frmWelcome.cs

Hình 15. Đổi tên form trong cửa sổ Solution Explorer

4.2. Thêm điều khiển hộp văn bản Textbox

Kích chuột vào biểu tượng trên hộp công cụ Toolbox, giữ và kéo chuột để đặt Textbox
vào Form. Ngoài ra ta có thể kích đúp chuột tại biểu tượng TextBox, điều khiển này sẽ được tự động
đặt vào Form.

Khi đã có điều khiển TextBox trong Form ta có thể thay đổi vị trí và kích thước của Textbox cho
phù hợp.

Khi mới xuất hiện trên Form hộp Textbox có tên mặc định là TextBox1, ta thay đổi giá trị này bằng
cách kích chuột chọn điều khiển TextBox1, tại cửa sổ Properties chọn thuộc tính Name sửa thành
txtWelcome.

4.3. Thêm điều khiển nút lệnh Button

Kích chuột vào biểu tượng , giữ và kéo chuột đưa điều khiển nút lệnh lên Form, nút lệnh
này có tên mặc định là Button1 và nội dung cũng là Button1.

Thực hiện tương tự đưa thêm 2 nút lệnh Button2 và Button3 vào form.

Bài giảng Cơ sở lập trình 2 19


Để thay đổi hai thuộc tính Name và Text của các nút lệnh ta thực hiện như sau:

 Kích chuột vào nút lệnh 1, trong cửa sổ Properties sửa thuộc tính Name là btnDisplay, thuộc
tính Text là Display

 Kích chuột vào nút lệnh 2, sửa thuộc tính Name là btnClear, thuộc tính Text là Clear

 Kích chuột vào nút lệnh 3, sửa thuộc tính Name là btnExit, thuộc tính Text là Exit

Chú ý: Mọi điều khiển đều có thuộc tính Name, để dễ dàng quản lý, gỡ rối chương trình ta nên đặt
tên điều khiển tương ứng với chức năng của nó và có tiếp đầu ngữ chỉ loại điều khiển ở đầu.

Ví dụ: Textbox có tiếp đầu ngữ - txt, Button - btn, Form - frm… Các tiếp đầu ngữ được viết chữ
thường, tên của điều khiển được viết hoa chữ cái đầu tiên, ví dụ: txtWelcome.

5. Viết code

5.1. Viết code cho nút lệnh btnDisplay

Ta mở cửa sổ soạn thảo Code Editor bằng cách kích đúp chuột vào nút Display. Trong cửa sổ Code,
C# định nghĩa sẵn cho chúng ta một không gian tên - namespace đại diện cho form đang xét và 2
dòng mở đầu và kết thúc cho sự kiện Click của nút Display.

Gõ vào giữa thủ tục btnDisplay_Click dòng lệnh gán giá trị ‘Welcome to Visual C# 2010’ cho thuộc
tính Text của điều khiển txtWelcome như sau:

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;

namespace Welcome
{
public partial class frmWelcome : Form
{
public frmWelcome()
{
InitializeComponent();
}
private void btnDisplay_Click(object sender, EventArgs e)
{
txtWelcome.Text = "Welcome to Visual C# 2010";
}
Bài giảng Cơ sở lập trình 2 20
}
}

Chú ý:

Hầu như tất cả các thủ tục xử lý một sự kiện nào đó của các điều khiển trên form đều có 2 đối số là
sender và e. Trong đó:

 Đối số sender có kiểu object đại diện cho đối tượng đã phát sinh sự kiện.

 Đối số e có kiểu EventArgs chứa các thông tin về sự kiện như: vị trí chuột, thời gian phát
sinh sự kiện…

 object sender: chính là đối tượng phát sinh ra event. Để sử dụng được nó thì bạn phải ép
kiểu lại cho đúng là dùng được. Ví dụ: (Button)sender
EventArgs e: đối tượng e chứa danh sách các thuộc tính bổ xung khi đối tượng phát sinh
event. Tùy theo đối tượng phát sinh event mà e có các thuộc tính tương ứng. Ví dụ: khi
phát sinh sự kiện MouseUp trên Button có dạng: bt_MouseUp(object sender,
MouseEventArgs e) trong đó: e.Button: chứa giá trị chuột trái hay phải được click lên
button

Ta có cấu trúc chung để gán giá trị cho thuộc tính của một điều khiển khi viết mã lệnh như sau:

<Tên điều khiển>.<Thuộc tính> = <Giá trị>;

Các thuộc tính của các điều khiển trong C# rất phong phú, C# cung cấp tiện ích Intellisence tự
động hiển thị một danh sách các thuộc tính của điều khiển sau khi ta gõ tên điều khiển và dấu
chấm ‘.’

Để lựa chọn một thuộc tính, ta có thể dùng phím mũi tên lên, xuống để lựa chọn hoặc gõ các ký
tự đầu của thuộc tính cần sử dụng, sau đó ấn phím Tab hoặc dấu cách để tự động chèn tên thuộc
tính vào dòng lệnh.

Hình 16. Tiện ích Intellisence


Bài giảng Cơ sở lập trình 2 21
Trong môi trường soạn thảo, nếu gõ sai cú pháp thì C# sẽ bắt lỗi ngay bằng cách hiển thị một
đường gạch chân hình răng cưa dưới câu lệnh sai. Khi sửa xong lỗi thì đường răng cưa sẽ tự động
biến mất.

5.2. Viết code cho nút lệnh btnClear

Quay lại cửa sổ thiết kế Design, kích đúp chuột vào nút Clear, gõ mã lệnh cho nút Clear như sau:

private void btnClear_Click(object sender, EventArgs e)


{
txtWelcome.Text = "";
}

5.3. Viết code cho nút lệnh btnExit

Quay lại cửa sổ thiết kế Design, kích đúp chuột vào nút Exit, gõ mã lệnh như sau:

private void btnExit_Click(object sender, EventArgs e)


{
Application.Exit();
}

Lệnh Application.Exit() có tác dụng đóng và xoá ra khỏi bộ nhớ tất cả các cửa sổ đang được thực
hiện trong chương trình và quay trở về cửa sổ thiết kế.

6. Lưu đồ án

Chọn File/Save All hoặc kích chọn biểu tượng trên thanh công cụ Standard.

7. Các tệp tin của đồ án

Khi tạo đồ án, Visual Studio.NET sinh ra các tập tin sau:

 .sln: đây là tập tin giải pháp (solution file), mỗi ứng dụng có một tập tin loại này nó bao gồm
một hoặc nhiều tập tin dự án.

 .csproj: đây là tập tin dự án (project file) của C#, mỗi tập tin dự án gồm một hoặc nhiều tập
tin nguồn, các tập tin nguồn trong cùng một dự án phải được viết cùng một ngôn ngữ.

 .cs: đây là tập tin nguồn (source file) của C# là nơi chứa mã lệnh của chương trình.

 AssemblyInfor.cs: tập tin này cho phép thêm một số thuộc tính vào chương trình như: tên tác
giả, ngày tạo chương trình…

8. Chạy chương trình

Để chạy một chương trình C# ta thực hiện theo 1 trong các cách sau:

Bài giảng Cơ sở lập trình 2 22


 Chọn Debug/Start Debugging.

 Kích chuột vào biểu tượng Start Debugging trên thanh công cụ Standard.

 Bấm phím tắt F5.

9. Dừng chương trình

Khi chạy chương trình, nếu xuất hiện lỗi ta có thể dừng chương trình và quay về cửa sổ soạn thảo để
sửa lỗi. Ta có các cách thực hiện sau:

 Vào Debug/Stop Debugging.

 Kích chuột vào biểu tượng Stop Debugging trên thanh công cụ Standard.

 Bấm phím tắt Ctrl+Alt+Break.

10. Mở đồ án đã có

Để mở một đồ án đã có ta có các cách thực hiện như sau:

 Mở thư mục chứa đồ án, ví dụ thư mục Welcome trong đường dẫn “D:\”, kích đúp vào tập
tin Welcome.sln để mở đồ án Welcome.

 Mở môi trường Microsoft Visual Studio 2010, trong cửa sổ Start Page kích chọn đồ án cần
mở trong mục Recent Projects (nếu có).

 Mở môi trường Microsoft Visual Studio 2010, vào File/Open Project, chọn đường dẫn đến
tệp tin .sln của đồ án rồi chọn Open.

11. Thoát khỏi Visual C# 2010

 Chọn File/Exit.

CHƯƠNG 3.
DỮ LIỆU VÀ CẤU TRÚC ĐIỀU KHIỂN

1. Biến, hằng và các kiểu dữ liệu

Bài giảng Cơ sở lập trình 2 23


1.1. Biến

Biến là một đại lượng dùng để chứa dữ liệu tạm thời trong quá trình tính toán. Tất cả các biến được
sử dụng trong chương trình đều phải được khai báo ngay từ đầu, biến được chia thành 3 loại bao
gồm: Biến đầu vào, biến đầu ra và biến trung gian.

Biến có thể được khai báo tại 2 nơi gồm:

 Bên trong phần định nghĩa lớp của Form.

 Bên trong một phương thức.

public partial class frmWelcome : Form


{
// Nơi khai báo biến;
private void bntDisplay_Click(object sender, EventArgs e)
{
// Nơi khai báo biến;
}
}

Phạm vi của một biến: phụ thuộc vào vị trí khai báo của biến, nếu biến được khai báo trong phần
định nghĩa lớp của Form thì là biến toàn cục có tác dụng trong toàn bộ các đoạn mã lệnh của form,
nếu biến được khai báo bên trong một phương thức thì là biến cục bộ chỉ có tác dụng trong phương
thức chứa nó.

Biến giống như những chiếc hộp trong bộ nhớ có khả năng lưu giữ giá trị, có nhiều kiểu giá trị khác
nhau mà C# có thể xử lý như: kiểu số nguyên, kiểu số thực, kiểu ký tự… Khi khai báo một biến ta
phải chỉ ra kiểu giá trị mà nó sẽ lưu trữ.

Cú pháp khai báo biến như sau:

Kiểu dữ liệu Tênbiến [=Giá trị];

Tênbiến: là một chuỗi các ký tự do người lập trình tự đặt bao gồm các chữ cái, chữ số và dấu gạch
dưới. Tên biến phải bắt đầu bằng một chữ cái, không được chứa dấu cách, C# phân biệt chữ hoa chữ
thường.

1.2. Hằng

Hằng là đại lượng dùng để chứa những dữ liệu có giá trị không đổi trong suốt quá trình tính toán. Sử
dụng hằng làm chương trình sáng sủa dễ đọc nhờ tên gọi gợi nhớ thay vì các con số.

Hằng được khai báo theo cú pháp sau:

const Kiểu dữ liệu Tênhằng = Giá trị;

1.3. Các kiểu dữ liệu


Bài giảng Cơ sở lập trình 2 24
1.3.1. Kiểu số

int, long: lưu trữ các số nguyên, int có độ lớn 4 bytes, long có độ lớn 8 bytes.
float, double: biểu diễn các số thực, kiểu float dùng 4 bytes, double dùng 8 bytes.

Ví dụ khai báo biến số:


int a; a=10;
long b=10L;
float c =19.34F;
double d=19.34;
Các phép toán số học:

 Cộng: +,+=

 Trừ: -, -=

 Nhân: *, *=

 Chia:/, /=. Ta có int/int=int, int/double=double, double/int=double, double/double=double Ví


dụ: 8/5=1; 8.0/5=1.6

Chú ý: các phép toán x[+,-,*,/]=y tương đương với phép toán: x=x[+,-,*,/]y

 %: phép chia lấy phần dư, ví dụ 5 % 2=1, 10.8 % 4 = 2.8

 Math.Round(x,n): hàm làm tròn số thực, ví dụ: Math.Round(11.346,2) = 11.35

 Math.Sin(x): hàm tính giá trị của sin(x)

 Math.Cos(x): hàm tính giá trị của cos(x)

 Math.Exp(x): hàm tính giá trị ex

 Math.Pow(x,y): hàm tính giá trị xy

 Math.Abs(x): hàm tính giá trị tuyệt đối của x

 Math.Sqrt(x): hàm tính căn bậc hai của x

 Math.Floor(x): hàm trả về số nguyên gần x nhất, ví dụ: Math.Floor(11.756) = 11

 Math.Truncate(x): hàm trả về phần nguyên của x, ví dụ: Math.Truncate(11.756) = 11

Ta có: Math.Floor(-11.756) = -12 và Math.Truncate(-11.756) = -11

Bài giảng Cơ sở lập trình 2 25


Các phép toán so sánh: kết quả trả về của các phép toán so sánh có dạng đúng hoặc sai.

 Lớn hơn: >

 Nhỏ hơn: <

 Lớn hơn hoặc bằng: >=

 Nhỏ hơn hoặc bằng: <=

 Bằng: ==

 Khác: !=

1.3.2. Kiểu ký tự - char


char là kiểu dữ liệu chứa các ký tự trong bảng mã ASCII và được đặt trong cặp dấu nháy đơn.

Khai báo biến ký tự:

char ch=’+’;

1.3.3. Kiểu chuỗi - string

string là một chuỗi các ký tự được đặt trong cặp dấu nháy kép. Trong VS.NET có hỗ trợ font
Unicode nên ta có thể gõ tiếng Việt có dấu.

Ví dụ khai báo biến chuỗi:

string s=”Hà Nội mùa thu”;

Các phép toán trên kiểu dữ liệu chuỗi

 +: toán tử ghép chuỗi.


Ví dụ: “Hà Nội ” + “mùa thu” cho kết quả “Hà Nội mùa thu”

 s.Length: trả về chiều dài của chuỗi s.


Ví dụ: “Lâm Anh”.Length có kết quả = 7

 s.Replace(str1,str2): thay thế chuỗi str1 trong chuỗi s bằng chuỗi str2.
Ví dụ: “Hà Nội”.Replace(“Nội”, “Tây”) cho kết quả “Hà Tây”

 s.Substring(vt,n): trả về một chuỗi con gồm n ký tự trong chuỗi s, bắt đầu từ ký tự ở vị trí vt.
(Chuỗi được tính từ vị trí 0).
Ví dụ: "Hoa hồng ".Substring(1, 2) cho kết quả “oa”

Bài giảng Cơ sở lập trình 2 26


 s.Insert(vt,str): chèn thêm giá trị của chuỗi str vào chuỗi s tại vị trí vt.
Ví dụ: "Trời xanh". Insert(4, " màu") cho kết quả “Trời màu xanh”

 s.ToLower: biến đổi chuỗi s về chữ in thường.


Ví dụ: “Hà Nội”.ToLower cho kết quả “hà nội”

 s.ToUpper: biến đổi chuỗi s về chữ in hoa.


Ví dụ: “Hà Nội”.ToUpper có kết quả “HÀ NỘI”

 s.Remove(vt,n): xóa n ký tự trong chuỗi s, bắt đầu từ ký tự ở vị trí vt.


Ví dụ: "Hoa hồng".Remove(1, 2) cho kết quả “H hồng”

 s.TrimStart: xóa các ký tự rỗng ở đầu chuỗi s.


Ví dụ: " Hoa hồng ".TrimStart cho kết quả "Hoa hồng "

 s.TrimEnd: xóa các ký tự rỗng ở cuối chuỗi s.


Ví dụ: " Hoa hồng ".TrimEnd cho kết quả " Hoa hồng"

 s.Trim: xóa các ký tự rỗng ở đầu và cuối chuỗi s.


Ví dụ: " Hoa hồng ".Trim cho kết quả "Hoa hồng"

 s.Split(ch): tách chuỗi s thành các chuỗi con ngăn cách nhau bởi ký tự ch.
Ví dụ: string s = "Ha Noi";
string[] tu=s.Split(‘ ‘);
Kết quả: tu[0]= "Ha", tu[1]= "Noi"

1.3.4. Kiểu logic bool

Kiểu bool là kiểu dữ liệu chỉ nhận một trong hai giá trị true/false.

Các phép toán trên kiểu dữ liệu bool

 Phép toán Và &&: xét biểu thức A && B chỉ nhận giá trị đúng khi và chỉ khi cả A và B
cùng nhận giá trị đúng, còn nhận giá trị sai trong tất cả các trường hợp còn lại

 Phép toán Hoặc ||: xét biểu thức A || B chỉ nhận giá trị sai khi và chỉ khi cả A và B cùng
nhận giá trị sai, còn nhận giá trị đúng trong tất cả các trường hợp còn lại.

 Phép toán Phủ định !: ta có !A nhận giá trị đúng khi A nhận giá trị sai và ngược lại.

Bảng giá trị chân lý của các phép toán:

A B A && B A || B A !A
Bài giảng Cơ sở lập trình 2 27
True True True True False True
True False False True True False
False True False True

False False False False

1.3.5. Kiểu ngày tháng DateTime

Ví dụ khai báo biến ngày tháng:

DateTime d;
d = DateTime.Now;

Các phép toán trên kiểu dữ liệu DateTime

 DateTime.Now: trả về ngày và giờ hiện hành, ví dụ: 09/02/2009 5:20:28PM

 Date.Day: trả về giá trị ngày của Date, ví dụ: d.Day cho kết quả 09

 Date.Month: trả về giá trị tháng của Date, ví dụ:d.Month cho kết quả 02

 Date.Year: trả về giá trị năm của Date, ví dụ: d.Year cho kết quả 2009

 Date.AddDays(n): trả về một ngày mới cách ngày Date n ngày.

 Date.AddMonths(n): trả về một ngày mới cách ngày Date n tháng.

 Date.AddYears(n): trả về một ngày mới cách ngày Date n năm.

1.3.6. Kiểu dữ liệu ngẫu nhiên


C# cung cấp kiểu dữ liệu Random cho phép sinh các số ngẫu nhiên. Ví dụ khai báo biến ngẫu nhiên:

Random rnd;

Các phép toán trên kiểu dữ liệu ngẫu nhiên

 new Random(): khởi tạo bộ số ngẫu nhiên. Ví dụ: rnd=new Random();

 rnd.NextDouble(): trả về một số thực ngẫu nhiên trong khoảng từ 0 đến 1.

 rnd.Next(): trả về một số nguyên có giá trị bất kỳ.

 rnd.Next(n,m): trả về một số nguyên có giá trị bất kỳ trong khoảng từ n tới m (n>=0).

Bài giảng Cơ sở lập trình 2 28


1.3.7. Kiểu dữ liệu mảng

Mảng là một tập hợp các biến có cùng tên và cùng kiểu dữ liệu. Dùng mảng làm chương trình đơn
giản và ngắn gọn hơn. Mảng có cận trên, cận dưới và các thành phần trong mảng là liên tục giữa 2
cận.

Khai báo mảng: mảng được khai báo theo cú pháp sau:

Kiểu dữ liệu[] tên mảng ;

Để cấp phát bộ nhớ cho mảng ta dùng toán tử new theo sau là tên kiểu dữ liệu và kích thước của
mảng được đặt trong cặp dấu ngoặc vuông.

Ví dụ khai báo mảng một chiều nguyên a gồm 10 phần tử :

int[] a = new int[10] ;

Khai báo mảng 2 chiều thực b gồm 10 hàng, 5 cột

double[,] b = new double[10,5];

Khởi tạo giá trị cho các phần tử của mảng khi khai báo:

double[] a = new double[2] {34.56, -45}; hoặc double[] a = {34.56, -45};

string[] Tennuoc = {“Anh”, “Pháp”, “Đức”, “Việt Nam”};

int[,] a = {{4, 6, 9}, {5, 7, 9}, {12, 44, 23}};

1.4. Hàm chuyển đổi giữa các kiểu dữ liệu

Hàm chuyển đổi Đổi giá trị sang kiểu

Convert.ToBoolean(Giatri) Boolean
Convert.ToByte(Giatri) Byte
Convert.ToDateTime(Giatri) Date
Convert.ToDouble(Giatri) Double
Convert.ToInt16(Giatri) Integer – 2 byte
Convert.ToInt32(Giatri) Integer – 4 byte
Convert.ToInt64(Giatri) Integer – 8 byte
Convert.ToSingle(Giatri) Single
Convert.ToString(Giatri) String

Bài giảng Cơ sở lập trình 2 29


Chú ý rằng giá trị truyền cho hàm phải hợp lệ, nghĩa là phải thuộc miền giá trị của kiểu kết quả nếu
không C# sẽ báo lỗi. Ví dụ:

+ Convert.ToDateTime(“25/04/79”) trả về giá trị kiểu ngày tháng 25/04/79

+ Convert.ToInt32(“25”) = 25

+ Convert.ToInt32(“25a”) hoặc Convert.ToInt32(“a25”) sẽ báo lỗi.

2. Hộp thoại thông báo – MessageBox

2.1. Khái niệm

Hộp thông báo là hộp thoại cung cấp thông tin để tương tác với người sử dụng, đồng thời cũng là
nơi hiển thị các kết quả trung gian trong quá trình tính toán.

Trong thời gian hiển thị hộp thông báo, C# ngừng mọi hoạt động của biểu mẫu và người dùng chỉ có
thể làm việc với hộp thông báo.

2.2. Hộp thông báo MessageBox

MessageBox.Show(Nội dung thông báo, Tiêu đề, Kiểu chức năng, Kiểu biểu tượng);

Chú ý: Cú pháp hộp thông báo không nhất thiết phải có đầy đủ bốn thành phần trên, nội dung cần
thông báo và tiêu đề của hộp thông báo được đặt trong cặp dấu nháy kép.

Kiểu chức năng và kiểu biểu tượng có các giá trị như sau:

Hằng tượng trưng Thể hiện Ý nghĩa

Các kiểu chức năng: được bắt đầu bởi MessageBoxButtons


.OK Chỉ hiển thị nút OK.
.OKCancel Hiển thị các nút OK và Cancel.
.AbortRetryIgnore Hiển thị các nút Abort, Retry và
Ignore.
.YesNoCancel Hiển thị các nút Yes, No và Cancel.
.YesNo Hiển thị các nút Yes, No.
.RetryCancel Hiển thị các nút Retry, Cancel.

Các kiểu biểu tượng: được bắt đầu bởi MessageBoxIcon


.Error hoặc .Hand hoặc .Stop Dùng cho những thông báo lỗi thất bại khi thi hành một
việc nào đó.

Bài giảng Cơ sở lập trình 2 30


.Question Dùng cho những câu hỏi yêu cầu người dùng chọn lựa.

.Exclamation hoặc .Warning Dùng cho các thông báo của chương trình.

.Asterisk hoặc .Information Dùng cho các thông báo cung cấp thêm thông tin cho
người dùng.
.None Không hiển thị biểu tượng.

Ví dụ hiển thị hộp thông báo “Bạn chưa nhập dữ liệu” với một nút lệnh OK và biểu tượng
Information ta viết như sau:

MessageBox.Show("Bạn chưa nhập dữ liệu", "Thông báo",


MessageBoxButtons.OK, MessageBoxIcon.Information)

Kết quả ta có:

Chú ý: Trong khi chạy chương trình ta có thể hiển thị giá trị hiện thời của một biến bất kỳ bằng hộp
thông báo như sau:

int a = 5;
MessageBox.Show(a.ToString());

Kết quả xuất hiện hộp hội thoại sau:

2.3. Hàm thông báo MessageBox

Ngoài chức năng thông báo, hàm MessageBox còn trả về giá trị của các nút chức năng mà người
dùng đã chọn. Cú pháp của hàm MessageBox như sau:

MessageBox.Show(Nội dung thông báo, Tiêu đề, Kiểu chức năng, Kiểu biểu tượng) = Giá trị trả về
Trong đó giá trị trả về gồm:

 System.Windows.Forms.DialogResult.OK

Bài giảng Cơ sở lập trình 2 31


 System.Windows.Forms.DialogResult.Cancel

 System.Windows.Forms.DialogResult.Abort

 System.Windows.Forms.DialogResult.Retry

 System.Windows.Forms.DialogResult.Ignore

 System.Windows.Forms.DialogResult.Yes

 System.Windows.Forms.DialogResult.No

Ví dụ, ta có thể viết lại code cho nút btnThoat với yêu cầu chỉ thoát khi người dùng trả lời có muốn
thoát như sau:

private void btnThoat_Click(object sender, EventArgs e)


{
if (MessageBox.Show("Bạn có muốn thoát khỏi chương trình không?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question)==
System.Windows.Forms.DialogResult.Yes)
Application.Exit();
}

3. Các cấu trúc điều khiển

3.1. Câu lệnh lựa chọn if

Dạng 1:

if (Điềukiện)
{
Khối lệnh;
}
Hoạt động: Nếu <Điều kiện> nhận giá trị đúng thì <Khối lệnh> được thực hiện.

Dạng 2:

if (Điều kiện)
{
Khối lệnh 1;
}
Else
{

Bài giảng Cơ sở lập trình 2 32


Khối lệnh 2;
}
Hoạt động: Nếu <Điều kiện> nhận giá trị đúng thì <Khối lệnh 1> được thực hiện, <Khối lệnh 2> bị
bỏ qua. Ngược lại nếu <Điều kiện> nhận giá trị sai thì <Khối lệnh 2> được thực hiện, <Khối lệnh 1>
bị bỏ qua.

3.2. Câu lệnh lựa chọn Case

switch (Biểu thức kiểm tra)


{
case <Biểu thức 1>:
Khối lệnh 1;
break;
case <Biểu thức 2>:
Khối lệnh 2;
break;
…………………..
default:
Khối lệnh n+1;
break;
}

Hoạt động: máy so sánh giá trị của <Biểu thức kiểm tra> với giá trị của các <Biểu thức i>. Nếu
<Biểu thức kiểm tra> có giá trị thỏa mãn <Biểu thức i> thì <Khối lệnh i> được thực hiện, sau đó
máy sẽ thoát ngay ra khỏi câu lệnh switch. Nếu <Biểu thức kiểm tra> không thỏa mãn <Biểu thức i>
nào thì <Khối lệnh n+1> được thực hiện.

Chú ý: nếu các biểu thức khác nhau cùng thực hiện chung một khối lệnh thì ta có thể viết gộp như
sau:

switch (Biểu thức kiểm tra)


{
case <Biểu thức 1>:
case <Biểu thức 2>:
Khối lệnh;
break;
…………………..
default:
Khối lệnh n+1;
break;
}

Bài tập 1.

Xây dựng chương trình thực hiện các phép toán theo giao diện sau (các phép toán bao gồm: +, - ,
*, /, %).
Bài giảng Cơ sở lập trình 2 33
Hình 17. Giao diện bài tập 1

Yêu cầu: + Nút thực hiện có tác dụng thực hiện phép toán đối với số A và số B, kết quả lưu
vào ô kết quả.

+ Kết quả chỉ được tính khi người dùng nhập đủ giá trị cho số A, B và phép toán.

+ Phép toán chia phải kiểm tra trường hợp mẫu =0.

+ Ô kết quả không được phép chỉnh sửa dữ liệu.

Tạo dự án mới và thiết lập các thuộc tính của các điều khiển như sau:

Điều khiển Thuộc tính Giá trị


Name frmPheptoan
FormBorderStyle Fixed3D
Form1
Icon Chọn file ảnh có đuôi .ico bất kỳ
Text Chuong trinh thuc hien cac phep toan
Lable1 Text Số A
Lable2 Text Số B
Lable3 Text Phép toán:
Lable4 Text Kết quả:
TextBox1 Name txtSoA
TextBox2 Name txtSoB
TextBox3 Name txtPheptoan
TextBox4 Name txtKetqua
Name btnThuchien
Button1
Text &Thuchien
Name btnLamlai
Button2
Text &Làm lại

Bài giảng Cơ sở lập trình 2 34


Name btnThoat
Button3
Text T&hoát
Mã lệnh:

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;

namespace WindowsFormsApplication3
{
public partial class frmPheptoan : Form
{

public frmPheptoan()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
txtKetqua.Enabled = false;
btnLamlai.Enabled = false;
}

private void btnThuchien_Click(object sender, EventArgs e)


{
int a, b, kq;
if (txtSoA.Text == "")
{
MessageBox.Show("Bạn phải nhập A", "Thông báo", MessageBoxButtons.OK,
MessageBoxIcon.Information);
txtSoA.Focus();
return;
}
if (txtSoB.Text == "")
{
MessageBox.Show("Bạn phải nhập B", "Thông báo", MessageBoxButtons.OK,
MessageBoxIcon.Information);
txtSoB.Focus();
return;
}
a = Convert.ToInt16(txtSoA.Text);
Bài giảng Cơ sở lập trình 2 35
b = Convert.ToInt16(txtSoB.Text);
switch (txtPheptoan.Text)
{
case "+":
kq=a+b;
txtKetqua.Text = kq.ToString();
break;
case "-":
kq=a-b;
txtKetqua.Text = kq.ToString();
break;
case "*":
kq = a * b;
txtKetqua.Text = kq.ToString();
break;
case "/":
if (txtSoB.Text == "0")
{
MessageBox.Show("Giá trị B phải khác 0!", "Thông Báo",
MessageBoxButtons.OK, MessageBoxIcon.Error);
txtSoB.Text = "";
txtSoB.Focus();
return;
}
kq = a / b;
txtKetqua.Text = kq.ToString();
break;
case "%":
kq = a % b;
txtKetqua.Text = kq.ToString();
break;
default:
MessageBox.Show("Bạn phải nhập lại phép toán", "Thông Báo",
MessageBoxButtons.OK, MessageBoxIcon.Error);
txtPheptoan.Text = "";
txtPheptoan.Focus();
return;
}
btnThuchien.Enabled = false;
btnLamlai.Enabled = true;
txtSoA.ReadOnly =true ;
txtSoB.ReadOnly = true ;
txtPheptoan.ReadOnly = true;
}

private void btnLamlai_Click(object sender, EventArgs e)

Bài giảng Cơ sở lập trình 2 36


{
txtSoA.Text = "";
txtSoA.ReadOnly = false;
txtSoB.Text ="";
txtSoB.ReadOnly = false;
txtPheptoan.Text = "";
txtPheptoan.ReadOnly = false;
txtKetqua.Text = "";
btnThuchien.Enabled = true;
txtSoA.Focus();
}

private void btnThoat_Click(object sender, EventArgs e)


{
if (MessageBox.Show("Bạn có muốn thoát không?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
System.Windows.Forms.DialogResult.Yes)
Application.Exit();
}
}
}

3.3. Cấu trúc lặp for

Cho phép thực hiện lặp đi lặp lại một đoạn chương trình nhiều lần, với số lần lặp xác định.

for (biểu thức khởi tạo; biểu thức điều kiện; biểu thức cập nhật)
{
Khối lệnh;
[break;]
}
Hoạt động: Đầu tiên máy thực hiện biểu thức khởi tạo để khởi tạo giá trị của biến điều khiển, sau đó
máy kiểm tra giá trị của biểu thức điều kiện, nếu biểu thức này đúng thì <Khối lệnh> được thực hiện
và cập nhật giá trị của biến điều khiển thông qua biểu thức cập nhật. Sau đó quay lại kiểm tra giá trị
của biểu thức điều kiện, cứ lặp lại như vậy cho đến khi biểu thức điều kiện nhận giá trị sai thì dừng
lại.

Chú ý: để thoát ngay ra khỏi vòng lặp for ta có thể dùng lệnh break.

Ví dụ: Dùng vòng lặp for để khởi tạo các giá trị ngẫu nhiên trong khoảng (0, 100) cho mảng một
chiều gồm 10 phần tử.

Mở một dự án mới rồi gõ đoạn mã sau vào cửa sổ code.

Bài giảng Cơ sở lập trình 2 37


private void Form1_Load(object sender, EventArgs e)
{
int[] m = new int[10];
Random rnd = new Random();
for(int i = 0; i<10; i++)
{
m[i] = rnd.Next(0,100);
MessageBox.Show(m[i].ToString());
}
}

Bấm F5 để thực hiện chương trình.

3.4. Cấu trúc lặp while

Cho phép thực hiện lặp đi lặp lại một đoạn chương trình nhiều lần, với số lần lặp không được xác
định trước.

while (Biểu thức điều kiện)


{
Khối lệnh;
[break;]
}
Hoạt động: Đầu tiên máy kiểm tra giá trị của <Biểu thức điều kiện>, nếu biểu thức này nhận giá trị
đúng thì <Khối lệnh> được thực hiện. Sau đó lại quay lại kiểm tra giá trị của <Biểu thức điều kiện>,
cứ lặp lại như vậy cho đến khi <Biểu thức điều kiện> nhận giá trị sai thì dừng lại.

Chú ý: + Vì <Biểu thức điều kiện> được kiểm tra trước, nên <Khối lệnh> có thể không được
thực hiện lần nào nếu ngay từ đầu <Biểu thức điều kiện> đã nhận giá trị sai và trước
khi thực hiện khối lệnh phải khởi gán giá trị cho <Biểu thức điều kiện>.

+ Trong <Khối lệnh> phải có ít nhất một lệnh làm thay đổi giá trị của <Biểu thức điều
kiện> để đến một lúc nào đó <Biểu thức điều kiện> nhận giá trị sai, nhằm dừng vòng lặp
lại, nếu không nó sẽ lặp mãi không dừng.

Ví dụ: Nhập số thực a, tìm số tự nhiên n nhỏ nhất sao cho tổng: T = 1+1/2+…+1/n >= a

Mở một dự án mới rồi gõ đoạn mã sau vào cửa sổ code.

private void Form1_Load(object sender, EventArgs e)


{
double a= 2;
double T= 0;
int n = 0;
while (T<a)
{
n = n + 1;
Bài giảng Cơ sở lập trình 2 38
T = T + 1.0/n;
}
MessageBox.Show("Gia tri n thoa man = " + n.ToString ());
}

Bấm F5 thực hiện chương trình, có thể thay đổi giá trị của a để có những kết quả khác nhau.

3.5. Cấu trúc lặp do…while

Cho phép thực hiện lặp đi lặp lại một đoạn chương trình nhiều lần, với số lần lặp không được xác
định trước.

Do
{
Khối lệnh;
[break;]
}
while (Biểu thức điều kiện);

Hoạt động: Đầu tiên máy thực hiện <Khối lệnh>, sau đó kiểm tra giá trị của <Biểu thức điều kiện>,
nếu biểu thức này nhận giá trị đúng thì tiếp tục thực hiện <Khối lệnh>, cứ lặp lại như vậy cho đến
khi <Biểu thức điều kiện> nhận giá trị sai thì dừng lại.

Chú ý: + Vì <Biểu thức điều kiện> được kiểm tra sau, nên <Khối lệnh> luôn được thực hiện
ít nhất 1 lần.

+ Trong <Khối lệnh> phải có ít nhất một lệnh làm thay đổi giá trị của <Biểu thức điều
kiện> nhằm dừng vòng lặp lại.

Ví dụ: Tính tổng T = 1 + 2 + … + 10

Mở một dự án mới rồi gõ đoạn mã sau vào cửa sổ code.

private void Form1_Load(object sender, EventArgs e)


{
int T = 0;
int i = 1;
do
{
T = T + i;
i = i + 1;
}
while (i <= 10);
MessageBox.Show("T = " + T.ToString ());
}

3.6. Câu lệnh try…catch

Bài giảng Cơ sở lập trình 2 39


Được dùng trong các câu lệnh bẫy lỗi của chương trình, cho phép bắt một số lỗi trong quá trình thực
thi ứng dụng, ví dụ: biến các ký tự không phải dạng số thành số, thực hiện phép chia cho 0, sử dụng
biến null…

Cú pháp bẫy lỗi trong C# được thể hiện như sau:

try
{
// mã cho việc thực thi bình thường
}
catch (System.Exception )
{
// xử lí lỗi
}
finally
{
// dọn dẹp
}

Cú pháp trên gồm 3 khối:

 Khối try chứa đựng đoạn mã cần phải thực thi trong chương trình, nhưng đoạn mã này có thể
gặp phải một vài trạng thái lỗi.

 Khối catch chứa đựng đoạn mã giải quyết những những lỗi xẩy ra trong try, tham số của
catch là các lớp bắt lỗi. C# có rất nhiều lớp bắt lỗi, trong đó System.Exception là lớp ở mức
cao nhất có thể bắt được mọi loại lỗi xẩy ra trong try.

 Khối finally chứa đựng đoạn mã dọn dẹp tài nguyên hoặc bất kì hành động nào bạn muốn
thực hiện sau khối try hay catch, khối này có thể có hoặc không.

Hoạt động: Đầu tiên chương trình thực thi các câu lệnh trong khối try, nếu không xuất hiện lỗi thì
các câu lệnh được thực hiện bình thường sau đó sẽ nhảy đến thực hiện các câu lệnh trong khối
finally, tuy nhiên nếu xuất hiện lỗi trong khối try thì chương trình sẽ tự động nhảy ngay tới thực thi
các câu lệnh trong khối catch mà không đột ngột dừng chương trình và sau đó cũng thực hiện các
câu lệnh trong khối finally.

Chú ý: C# không cho phép đặt lệnh return bên trong khối finally.

Ví dụ: Bẫy lỗi đoạn chương trình tính tổng 2 số nguyên a và b trong trường hợp không nhập dữ liệu
dạng số.

private void bntTong_Click(object sender, EventArgs e)


{
try
{
txtTong.Text = Convert.ToString(Convert.ToInt32(txtSoA.Text)
Bài giảng Cơ sở lập trình 2 40
+ Convert.ToInt32(txtSoB.Text));
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
//MessageBox.Show("Bạn phải nhập dữ liệu số!");
}
}

4. Hàm

4.1. Hàm có một giá trị trả về

Cú pháp xây dựng:

public|private Kiểudữliệutrảvề <Tên CTC>([Tham số])


{
Khai báo các biến cục bộ;
Kiểudữliệutrảvề BiếnTG;
Tính toán kết quả thông qua BiếnTG;
return BiếnTG;
}

Khi xây dựng hàm có giá trị trả về ta thường khai báo thêm một biến trung gian có kiểu trùng với
kiểu dữ liệu trả về và công thức tính toán sẽ được tính thông qua biến trung gian này. Giá trị của
biến trung gian sẽ được gán vào cho tên hàm thông qua lệnh return.

Lệnh return có thể được đặt tại vị trí bất kỳ, khi gặp lệnh return chương trình gán giá trị của biến đi
kèm sau lệnh return cho tên hàm và thoát ngay ra khỏi hàm.

4.2. Hàm không có giá trị trả về

Cú pháp xây dựng:

public|private void <Tên CTC>([Tham số])


{
Các dòng lệnh;
}

4.3. Cách gọi hàm

Hàm có giá trị trả về: được sử dụng như một thành phần của biểu thức, điều đó có nghĩa nó có thể
được dùng trong lệnh gán và trong các biểu thức so sánh.

Biến = <Tên CTC>([Tham số]);

Ví dụ, nếu ta có hàm: private double MyFunction(int a, int b)

Bài giảng Cơ sở lập trình 2 41


Thì ta gọi hàm như sau: x = MyFunction(n, m);

Trong đó x là biến có kiểu double, n và m là hai biến int tương ứng với a và b.

Hàm không có giá trị trả về: được dùng như một câu lệnh độc lập, nó không được dùng trong lệnh
gán hoặc trong các biểu thức so sánh.

<Tên thủ tục>([Tham số]);

Giả sử ta có hàm: private void MySub(int a, int b)

Khi đó hàm được gọi như sau: MySub (a, b);

Chú ý: Các tham số khi xây dựng hàm được gọi là tham số hình thức, các tham số khi sử dụng hàm
gọi là tham số thực sự, hai loại tham số này phải tương ứng nhau về: số lượng, thứ tự và kiểu dữ
liệu.

4.4. Ví dụ minh họa

Viết và thực hiện hàm tính k! và hàm bẫy lỗi chia cho 0. Mở một dự án mới rồi gõ đoạn mã sau vào
cửa sổ code.

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
double a;

private double Giaithua(int k )


{
double gt;
int i;
gt = 1;
for(i=1;i<=k;i++)
gt = gt * i;
return gt;
}

private void Division()


{
int i=0;
int n;
try

Bài giảng Cơ sở lập trình 2 42


{
n = 4 / i;
MessageBox.Show(n.ToString());
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
}

private void Form1_Load(object sender, EventArgs e)


{
a = Giaithua(6);
MessageBox.Show(a.ToString());
Division();
}
}
}
5. Gỡ rối chương trình

Ở trong những giai đoạn đầu lập trình các chương trình không tránh khỏi có sai sót và mắc lỗi, tuy
nhiên ta có thể giảm khả năng mắc lỗi đến mức tối thiểu bằng cách thực hiện một số giải pháp giảm
lỗi như sau:

 Thiết kế cẩn thận, ghi chú các vấn đề quan trọng và cách giải quyết cho từng phần. Ghi chú
từng thủ tục và mục đích của nó.

 Chú thích rõ ràng trong chương trình (trong C# dòng chú thích được bắt đầu bởi 2 dấu gạch
chéo //).
Để đặt chú thích cho các dòng lệnh, ta có thể gõ 2 dấu gạch chéo // tại vị trí cần đặt chú
thích, hoặc bôi đen các dòng lệnh rồi kích chọn biểu tượng trên thanh công cụ Standard.
Để xóa dấu chú thích ở các dòng lệnh, ta có thể xóa 2 dấu gạch chéo // hoặc bôi đen các
dòng lệnh muốn xóa dấu chú thích rồi kích chọn biểu tượng trên thanh công cụ Standard.

 Dùng cửa sổ danh sách các thuộc tính, các phương thức, các hằng số, các lớp đối tượng…
trong C# để tránh việc gõ sai tên thuộc tính, phương thức…

Để gọi cửa sổ này, trong cửa sổ soạn thảo code bấm tổ hợp phím Ctrl+J, kết quả khi người
dùng gõ các ký tự bất kỳ, con trỏ sẽ tự động cuộn tới dòng đầu tiên chứa các ký tự đó cho
người dùng chọn.

Bài giảng Cơ sở lập trình 2 43


Hình 18. Cửa sổ danh sách thuộc tính, phương thức, sự kiện.

 Sử dụng câu lệnh try…catch để bắt các lỗi ngoại lệ của chương trình.

CHƯƠNG 4.
TÌM HIỂU CÁC ĐIỀU KHIỂN CƠ BẢN

1. Tìm hiểu thuộc tính, phương thức và sự kiện

Mỗi một đối tượng trong C# đều có 3 đặc tính là Thuộc tính - Properties, Phương thức - Methods và
Sự kiện – Events. Trong đó:

 Properties: là tập hợp các thuộc tính để mô tả một đối tượng như: tên, chiều cao, chiều rộng,
mầu chữ, mầu nền… Các thuộc tính có thể xác định trong khi thiết kế (Design time) hoặc
trong lúc thi hành (Run time).

 Methodes: là những đoạn chương trình chứa trong điều khiển, cho điều khiển biết cách thức
để thực hiện một công việc nào đó, chẳng hạn làm ẩn sự xuất hiện của một điều khiển
(phương thức Hide).

 Evens: nếu thuộc tính mô tả đối tượng, phương thức chỉ ra cách thức đối tượng hành động
thì sự kiện là những phản ứng của đối tượng. Khi tạo một chương trình trong C#, ta lập trình
chủ yếu theo sự kiện, lập trình theo cách này có nghĩa là ta phải biết khi nào sự kiện xảy ra
và làm gì khi sự kiện đó xảy ra? Điều này có nghĩa là chương trình chỉ thi hành khi người
dùng thực hiện một thao tác nào đó trên giao diện.

2. Mối quan hệ giữa thuộc tính, phương thức và sự kiện

Bài giảng Cơ sở lập trình 2 44


Mặc dù thuộc tính, phương thức và sự kiện có vai trò khác nhau nhưng chúng thường xuyên liên hệ
với nhau. Ví dụ, nếu ta di chuyển một điều khiển bằng phương thức Move thì một số thuộc tính như
Top, Height, Left, Width sẽ thay đổi theo theo, khi đó kích cỡ của điều khiển thay đổi tức là sự kiện
Resize xảy ra.

Phụ thuộc lẫn nhau còn có nghĩa là ta có thể thực hiện một công việc bằng nhiều cách: xử lý trên
thuộc tính hoặc xử lý bằng phương thức.

Ví dụ: ta có 2 cách để làm hộp văn bản textBox1 xuất hiện và biến mất trên màn hình:

 Thực hiện bằng thuộc tính:

Xuất hiện: textBox1.Visible = true;


Biến mất: textBox1.Visible = false;

 Thực hiện bằng phương thức:

Xuất hiện: textBox1.Show();


Biến mất: textBox1.Hide();

3. Thuộc tính, phương thức, sự kiện của một số điều khiển cơ bản

3.1. Form

3.1.1. Thuộc tính

Name Tên form, bắt đầu bởi tiếp đầu ngữ frm
BackColor Thiết lập mầu nền cho Form.
BackgroundImage Thiết lập ảnh nền cho Form.
BackgroundImageLayout Thiết lập chế độ hiển thị ảnh nền trên Form. Tile: hiển thị ảnh từ
trên xuống, Center: hiển thị ảnh từ giữa ra, Stretch: dãn đều ảnh
trên Form.
AcceptButton Thiết lập nút lệnh Accept. Sự kiện Click của nút lệnh này được gọi
bất cứ khi nào người dùng bấm phím Enter.
CancelButton Thiết lập nút lệnh Cancel. Sự kiện Click của nút lệnh này được gọi
bất cứ khi nào người dùng bấm phím Esc.
Cursor Thiết lập chế độ hiển thị con trỏ trên Form.
Enabled Nếu nhận giá trị True thì cho phép người dùng tác động lên Form,
ngược lại thì nhận giá trị False.
Font Thiết lập kiểu chữ, cỡ chữ cho các điều khiển trên Form.
ForeColor Thiết lập mầu chữ cho các điều khiển trên Form.
FormBorderStyle Thiết lập kiểu đường viền cho Form. Fixed Single: không thể thay

Bài giảng Cơ sở lập trình 2 45


đổi kích thước của Form, Sizable: có thể phóng to thu nhỏ và thay
đổi kích thước của Form, Sizable ToolWindow: có thể thay đổi
kích thước của Form…
Icon Thiết lập biểu tượng cho Form (các tệp ảnh có đuôi .ico).
MainMenuStrip Gắn kết Form với Menu.
Opacity Thiết lập độ trong suốt cho nền của Form, nếu độ trong suốt <
100% thì có thể nhìn xuyên thấu những gì nằm bên dưới Form.
ShowIcon Nếu nhận giá trị True thì cho phép hiển thị biểu tượng đã được
thiết lập ở thuộc tính Icon, ngược lại thì nhận giá trị False.
StartPosition Thiết lập vị trí xuất hiện của Form trên màn hình. Manual: xuất
hiện ở góc trên bên trái màn hình, CenterScreen: giữa màn hình…
Text Thiết lập dòng tiêu đề của Form.
Window State Thiết lập trạng thái của Form khi chạy chương trình. Normal: hiển
thị Form đúng theo kích cỡ thiết kế, Maximized: phóng to Form
bằng màn hình, Minimized: thu nhỏ Form trên thanh Taskbar.

3.1.2. Sự kiện

Để hiển thị danh sách các sự kiện của các điều khiển, ta kích chuột tại biểu tượng trên cửa sổ
Properties:

Hình 19. Danh sách sự kiện của điều khiển Form

Muốn gọi sự kiện nào thì ta kích đúp chuột vào tên sự kiện đó, kết quả C# sẽ tự động tạo ra dòng
tiêu đề của phương thức chứa sự kiện trong cửa sổ code.

Bài giảng Cơ sở lập trình 2 46


Form có một số sự kiện thông dụng như sau:

Load Được kích hoạt khi Form được nạp vào bộ nhớ, nó thường được dùng để khởi
tạo các giá trị và trạng thái cho các biến, các điều khiển… trên Form.
Click Được kích hoạt khi người dùng kích chuột trên Form.
FormClosed Được kích hoạt khi người dùng kích chuột vào nút Close x ở góc trên bên phải
để đóng Form.
FormClosing Cũng được kích hoạt khi người dùng kích chuột vào nút Close x, nhưng xảy ra
trước sự kiện FormClosed tức là được phát sinh trước khi cửa sổ Form chuẩn bị
đóng lại.

Ví dụ: Nếu không muốn người dùng đóng Form bằng cách bấm chọn biểu tượng Close thì trong thủ
tục FormClosing ta đặt thuộc tính Cancel = True như sau:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)


{
e.Cancel = true;
}
3.2. Hộp văn bản - TextBox

Hộp văn bản là điều khiển rất thông dụng, dùng để nhập dữ liệu đầu vào từ phía người
sử dụng và hiển thị các kết quả đã tính toán được.

3.2.1. Thuộc tính

Name Tên Textbox, bắt đầu bởi tiếp đầu ngữ txt
BackColor Thiết lập mầu nền cho hộp TextBox.
Enabled Enabled=False: không cho phép người dùng truy cập vào TextBox (Hộp
Textbox bị mờ đi), ngược lại thì bằng True.
Font Thiết lập kiểu chữ và cỡ chữ cho hộp văn bản.
ForeColor Thiết lập mầu chữ cho hộp văn bản.
Locked Locked = True: khóa không cho phép dịch chuyển vị trí của hộp văn bản trên
Form, ngược lại thì nhận giá trị False.
MaxLength Quy định chiều dài tối đa được chấp nhận của hộp văn bản, giá trị mặc định
là 32767 hoặc 0, tức là có thể chứa 32767 ký tự. Mọi xác lập khác 0, ví dụ 5
thì chỉ cho phép người dùng nhập tối đa 5 ký tự vào hộp văn bản.
Multiline Multiline = False: chỉ cho phép hiển thị văn bản trên một dòng, và khi thiết
kế ta chỉ thay đổi được độ dài của hộp văn bản.
Multiline = True: cho phép văn bản được hiển thị trên nhiều dòng, và có thể
thay đổi cả độ dài lẫn độ rộng của hộp văn bản khi thiết kế.

Bài giảng Cơ sở lập trình 2 47


PasswordChar Thuộc tính này cho phép người sử dụng bảo mật được thông tin nhập vào
Textbox. Ví dụ đặt thuộc tính này bằng ký tự ‘*’ khi đó toàn bộ dữ liệu nhập
vào sẽ được hiển thị dưới dạng dấu hoa thị.
ReadOnly ReadOnly = True: hộp văn bản vẫn được truy cập nhưng người dùng không
thể thay đổi được nội dung bên trong.
ScrollBars Thiết lập thanh cuốn ngang, dọc cho hộp văn bản (có hiệu lực khi Multiline
= True). Chú ý: thanh cuốn ngang chỉ có hiệu lực khi WordWrap = False.
TabIndex Thứ tự truy cập của hộp văn bản khi người dùng bấm phím Tab, thứ tự đầu
tiên là 0.
Text Chứa nội dung của hộp văn bản.
TextAlign Thiết lập chế độ căn chỉnh: trái, phải hoặc giữa của dữ liệu trong hộp
TextBox.
Visible Visible = True: hiển thị hộp văn bản, Visible = False: ẩn hộp văn bản.
WordWrap WordWrap = True: dòng văn bản được tự động cuộn xuống dòng khi gặp lề
bên phải của hộp TextBox, ngược lại thì nhận giá trị False. Chỉ có hiệu lực
khi Multiline = True.
3.2.2. Sự kiện

Hộp văn bản có một số sự kiện cơ bản sau:

TextChanged Được kích hoạt khi người dùng thực hiện sự thay đổi bất kỳ trong hộp
văn bản như: thêm, xoá, sửa, dán văn bản.
Click Được kích hoạt khi người dùng kích chuột vào hộp văn bản.
DoubleClick Được kích hoạt khi người dùng kích đúp chuột vào hộp văn bản.
GotFocus Được kích hoạt khi người dùng chuyển tiêu điểm tới hộp văn bản.
KeyPress Trả về ký tự (trừ các ký tự đặc biệt như phím Delete, Home, Ctrl, F1…)
mà người sử dụng gõ vào hộp văn bản thông qua thuộc tính KeyChar.
KeyDown Trả về mã Ascii của tất cả các ký tự mà người sử dụng gõ vào hộp văn
bản thông qua thuộc tính KeyCode.
LostFocus Được kích hoạt khi hộp văn bản mất tiêu điểm.
MouseMove Được kích hoạt khi người dùng di chuyển chuột qua hộp văn bản.
MouseLeave Được kích hoạt khi người dùng dời chuột ra khỏi hộp văn bản.

Ví dụ 1: Để hiển thị mã Ascii của một ký tự bất kỳ được gõ vào hộp văn bản TextBox1 ta có đoạn
chương trình như sau:

private void textBox1_KeyDown(object sender, KeyEventArgs e)


{

Bài giảng Cơ sở lập trình 2 48


int a;
a = Convert.ToInt32(e.KeyCode);
MessageBox.Show(a.ToString());
}

Ví dụ 2: Dùng sự kiện KeyPress để kiểm tra việc nhập dữ liệu, sự kiện này xảy ra sau khi một
phím được nhấn nhưng trước khi nó được hiển thị, ta sử dụng thông số sự kiện KeyPressEventArgs
để hủy bỏ cú nhấn phím không hợp lệ bằng cách đặt thuộc tính Handled là true.

Đoạn mã lệnh sau chỉ cho phép nhập vào hộp văn bản TextBox1 các số từ 0 tới 9, dấu âm - , dấu
chấm thập phân, phím Del (mã Ascii=13), phím Backspace (mã Ascii=8) để xóa dữ liệu

 Các phương thức xử lý sự kiện của các điều khiển thường gồm 2 tham số: sender và e

 sender có kiểu object: đại diện cho đối tượng phát sinh sự kiện

 e có kiểu EventArgs: chứa các thông tin về sự kiện: vị trí chuột, thời gian phát sinh
sự kiện…

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)


{
if (((e.KeyChar >='0') && (e.KeyChar <='9')) ||(e.KeyChar ==
'-') ||
(e.KeyChar == '.') || (Convert.ToInt32(e.KeyChar) == 8) ||
(Convert.ToInt32(e.KeyChar) == 13))
e.Handled = false;
else
e.Handled = true;
}
Về tổng quan thì các sự kiện trên đều có chức năng nhận các phím ký tự
trong khi được nhấn xuống. Nhưng về hình thức thì có một chút khác nhau.

 KeyDown: Sự kiện này xảy ra ngay khi người dùng nhấn một phím
trên bàn phím. Và có thể lặp lại khi người dùng nhấn giữ phím.
 KeyPress: Sự kiện này xảy ra khi người dùng nhấn vào một phím và
sau đó được thả ra.
 KeyUp: Sự kiện này xảy ra khi người dùng nhả một phím trên bàn
phím.

https://freetuts.net/keypress-keydown-keyup-trong-c-sharp-winforms-
5503.html

3.3. Nút lệnh – Button

Bài giảng Cơ sở lập trình 2 49


Nút lệnh cho phép người dùng thực hiện một hành động nào đó.

3.3.1. Thuộc tính

Name Tên nút lệnh, bắt đầu bởi tiếp đầu ngữ btn
BackColor Thiết lập mầu nền cho nút lệnh.
BackgroundImage Thiết lập ảnh nền cho nút lệnh.
Enabled Enabled=False: người dùng không thể tác động lên nút lệnh, ngược lại
thì bằng True.
Font Xác lập kiểu chữ và cỡ chữ cho nút lệnh.
ForeColor Thiết lập mầu chữ cho nút lệnh.
Image Thiết lập ảnh hiển thị trên nút lệnh.
Locked Locked = True: khóa không cho phép dịch chuyển vị trí của nút lệnh
trên Form, ngược lại thì nhận giá trị False.
TabIndex Thứ tự truy cập của nút lệnh khi người dùng bấm phím Tab.
Text Tiêu đề của nút lệnh. Ta có thể quy định phím nóng cho nút lệnh bằng
cách đặt dấu “&” trước một ký tự của Text.
Ví dụ &Quit sẽ được hiển thị là Quit, khi người sử dụng bấm Alt+Q
chương trình sẽ kích hoạt nút lệnh Quit.
Visible Visible = True: hiển thị nút lệnh, Visible = False: ẩn nút lệnh.

3.3.2. Sự kiện

Nút lệnh có một số sự kiện cơ bản sau:

Click Được kích hoạt khi người dùng kích chuột vào nút lệnh.
GotFocus Được kích hoạt khi người dùng chuyển tiêu điểm tới nút lệnh.
LostFocus Được kích hoạt khi nút lệnh mất tiêu điểm.
MouseDown Được kích hoạt khi người dùng đặt chuột vào nút lệnh.
MouseUp Được kích hoạt khi người dùng đưa chuột ra khỏi nút lệnh.
MouseMove Được kích hoạt khi người dùng di chuyển chuột trên nút lệnh.
MouseLeave Được kích hoạt khi người dùng dời chuột ra khỏi nút lệnh.
3.4. Nhãn – Lable

Nhãn dùng để hiển thị những thông tin có tính chất cố định người sử dụng không có khả
năng thay đổi ví dụ như dòng thông báo, hướng dẫn …

Bài giảng Cơ sở lập trình 2 50


Nhãn có một số thuộc tính hay dùng sau:

Name Tên nhãn, bắt đầu bởi tiếp đầu ngữ lbl
BackColor Thiết lập mầu nền cho nhãn, nếu thiết lập BackColor = Transparent (mục
lựa chọn đầu tiên trong tab Web) thì nhãn sẽ có nền giống với nền của
Form.
BorderStyle Thiết lập kiểu đường viền cho nhãn.
Font Thiết lập kiểu chữ và cỡ chữ cho nhãn.
ForeColor Thiết lập mầu chữ cho nhãn.
Image Thiết lập ảnh hiển thị trên nhãn.
Locked Locked = True: khóa không cho phép dịch chuyển vị trí của nhãn trên
Form, ngược lại thì nhận giá trị False.
TabIndex Thứ tự truy cập của nhãn khi người dùng bấm phím Tab.
Text Tiêu đề của nhãn.
TextAlign Thiết lập chế độ căn chỉnh: trái, phải hoặc giữa của tiêu đề nhãn.
Visible Hiện hoặc ẩn nhãn.

3.5. Dòng mách nước - ToolTip

Điều khiển mách nước cho phép hiển thị các thông tin chú thích khi người dùng đưa
chuột qua điều khiển có thiết lập ToolTip.

Ví dụ dòng mách nước “Hãy nhập tên truy cập” như hình dưới đây.

Hình 20. Ví dụ ToolTip

Để tạo dòng mách nước cho một điều khiển ta thực hiện như sau:

 Kéo điều khiển ToolTip vào Form, điều khiển ToolTip không được hiển thị ở trên Form mà
được hiển thị ở thanh ngang cuối Form và được dùng chung cho mọi điều khiển trên form.

Bài giảng Cơ sở lập trình 2 51


 Kích chuột chọn điều khiển muốn tạo ToolTip, trong cửa sổ Window Properties gõ nội dung
dòng ToolTip tại thuộc tính ToolTip on ToolTip1.

3.6. Bài tập

Bài tập 2.

Lập chương trình nhập tháng và năm dương lịch, tính và in ra số ngày của tháng và năm đó.

Hình 21. Giao diện bài tập 2

Yêu cầu: + Chỉ được phép nhập số nguyên vào hai hộp văn bản chứa tháng và năm.

+ Tháng phải có giá trị từ 1 đến 12, năm gồm 4 chữ số và có giá trị >=1900.

+ Kết quả chỉ được tính khi người dùng nhập đủ cả tháng và năm.

Tạo dự án mới và thiết lập các thuộc tính của các điều khiển như sau:

Điều khiển Thuộc tính Giá trị


Name frmNgaythang
FormBorderStyle Fixed3D
Form1
Icon Chọn file ảnh có đuôi .ico bất kỳ
Text Program of date
Lable1 Text Nhập tháng
Lable2 Text Nhập năm
Lable3 Name lblKetqua
Text Kết quả:
Name txtNhapthang
TextBox1
MaxLength 2
TextBox2 Name txtNhapnam

Bài giảng Cơ sở lập trình 2 52


MaxLength 4
Name btnKetqua
Button1
Text &Kết quả
Name btnLamlai
Button2
Text &Làm lại
Name btnThoat
Button3
Text &Thoát

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;

namespace WindowsFormsApplication1
{
public partial class frmNgaythang : Form
{
public frmNgaythang()
{
InitializeComponent();
}

private void txtNhapthang_KeyPress(object sender,


KeyPressEventArgs e)
{
if (((e.KeyChar >='0') && (e.KeyChar <='9'))||
(Convert.ToInt32(e.KeyChar)==8))
e.Handled = false;
else
e.Handled = true;
}

private void txtNhapnam_KeyPress(object sender, KeyPressEventArgs


e)
{
if (((e.KeyChar >='0') && (e.KeyChar <='9'))||
(Convert.ToInt32(e.KeyChar)==8))
e.Handled = false;
else
e.Handled = true;
Bài giảng Cơ sở lập trình 2 53
}

private void btnKetqua_Click(object sender, EventArgs e)


{
int thang, nam, ngay = 0;
if (txtNhapthang.Text == "")
{
MessageBox.Show("Bạn phải nhập tháng", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
txtNhapthang.Focus();
return;
}
if (txtNhapnam.Text.Length != 4)
{
MessageBox.Show("Bạn phải nhập năm có 4 chữ số", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapnam.Focus();
txtNhapnam.Text = "";
return;
}
thang = Convert.ToInt32(txtNhapthang.Text);
nam = Convert.ToInt32(txtNhapnam.Text);
if (thang > 12 || thang < 0)
{
MessageBox.Show("Bạn phải nhập tháng trong [1,12]",
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapthang.Focus();
txtNhapthang.Text = "";
return;
}
if (nam < 1900)
{
MessageBox.Show("Bạn phải nhập năm có giá trị >= 1900",
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapnam.Focus();
k txtNhapnam.Text = "";
return;
}
switch (thang)
{
case 4:

Bài giảng Cơ sở lập trình 2 54


case 6:
case 9:
case 11:
ngay = 30;
break;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
ngay = 31;
break;
case 2:
if (((nam % 4 == 0) && (nam % 100 != 0))||(nam % 400
== 0))
ngay = 29;
else
ngay = 28;
break;
}
lblKetqua.Text = "Tháng " + thang + " năm " + nam + " có " +
ngay + " ngày";
btnKetqua.Enabled = false;
btnLamlai.Enabled = true;
txtNhapthang.ReadOnly = true;
txtNhapnam.ReadOnly = true;
}

private void btnLamlai_Click(object sender, EventArgs e)


{
txtNhapthang.Text = "";
txtNhapthang.ReadOnly = false;
txtNhapthang.Focus();
txtNhapnam.Text = "";
txtNhapnam.ReadOnly = false;
btnKetqua.Enabled = true;
lblKetqua.Text = "Kết quả: ";
}

private void btnThoat_Click(object sender, EventArgs e)


{
if (MessageBox.Show("Bạn có muốn thoát không?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==

Bài giảng Cơ sở lập trình 2 55


System.Windows.Forms.DialogResult.Yes)
Application.Exit();
}
}
}

Bài tập 3.

Nhập 2 số nguyên a, b và tính tổng các số từ a đến b theo giao diện sau:

Hình 22. Giao diện bài tập 3

Yêu cầu:

 Tạo dòng ToolTip “Nhập số nguyên” cho 2 hộp văn bản ‘Nhập a’ và ‘Nhập b’.

 Chỉ cho phép người dùng nhập số vào hai hộp văn bản.

 Nút Tổng: kiểm tra người dùng phải nhập dữ liệu cho cả hai số a và b, tính tổng các số từ a
đến b nếu a < b, hoặc tính tổng các số từ b đến a nếu b < a, rồi hiển thị kết quả vào nhãn ở
phía dưới.

 Nút Làm lại: xóa các dữ liệu cũ ở các điều khiển, sau đó đặt con trỏ vào hộp văn bản Nhập a.

 Nút Thoát: thoát khỏi chương trình quay về môi trường soạn thảo.

Bài tập 4.

Nhập số nguyên dương n, tạo n số nguyên ngẫu nhiên có giá trị từ 1 tới 100, và thực hiện các yêu
cầu sau:

 Chỉ cho phép người dùng nhập số vào hộp văn bản Nhập n.

Bài giảng Cơ sở lập trình 2 56


 Nút Nhập: kiểm tra người dùng phải nhập giá trị cho n, sau đó tạo n số ngẫu nhiên và hiển
thị các số ngẫu nhiên đó ở nhãn Dẫy số.

 Nút Tính tổng: tính tổng n số ngẫu nhiên và hiển thị kết quả ở nhãn Tổng dẫy số.

 Nút Sắp xếp: sắp xếp n số ngẫu nhiên theo thứ tự tăng dần và hiển thị kết quả ở nhãn Sắp
xếp.

 Nút Làm lại: xóa các dữ liệu cũ ở các điều khiển, sau đó đặt con trỏ vào hộp văn bản Nhập n.

 Nút Thoát: thoát khỏi chương trình quay về môi trường soạn thảo.

Hình 23. Giao diện bài tập 4

Trang 37_Ví dụ: Dùng vòng lặp for để khởi tạo các giá trị ngẫu nhiên trong khoảng (0, 100) cho
mảng một chiều gồm 10 phần tử.

Mở một dự án mới rồi gõ đoạn mã sau vào cửa sổ code.

private void Form1_Load(object sender, EventArgs e)


{
int[] m = new int[10];
Random rnd = new Random();
for(int i = 0; i<10; i++)
{
m[i] = rnd.Next(0,100);
MessageBox.Show(m[i].ToString());
}
}

Bài giảng Cơ sở lập trình 2 57


Bài tập 5.

Hộp thoại MessageBox của C# tuy rất đa dạng và phong phú nhưng có lúc ta cũng cần một hộp
thoại tương tự theo phong cách riêng của mình, ví dụ hiển thị tiêu đề cho các nút nhấn bằng tiếng
Việt.

Ví dụ: viết chương trình tự tạo hộp thoại thông báo thực hiện các yêu cầu theo giao diện sau:

Hình 24. Giao diện bài tập 5

Kích chuột vào nút Thoát trên Form1 sẽ xuất hiện hộp thông báo Bạn có muốn thoát không? với
giao diện tiếng Việt. Chọn nút Có để đóng Form1 và thoát khỏi chương trình, chọn nút Không để
quay lại Form1.

Trong đó hộp thông báo Bạn có muốn thoát không? chính là một form được thiết kế tương tự như
một hộp thoại thông báo.

Bước 1: Xây dựng Form1

Vào Microsoft Visual Studio 2010 tạo một dự án mới có tên Hopthoai và thiết lập các thuộc tính
của các điều khiển như sau:

Điều khiển Thuộc tính Giá trị


Name Form1
Form1
StartPosition CenterScreen
Name btnThoat
Button1
Text Thoát

Bước 2: Xây dựng form Thông báo

Ta bổ sung thêm một form mới vào dự án theo các bước sau:

 Chọn menu Project | Add Windows Forms xuất hiện hộp thoại Add New Item.

Bài giảng Cơ sở lập trình 2 58


 Chọn Windows Form và đặt tên Message.cs tại ô Name rồi chọn nút Add. Kết quả form
Message.cs được thêm vào dự án.

 Thay đổi kích thước của form Message.cs như hình trên và thiết lập các thuộc tính của
các điều khiển trên form như sau:

Điều khiển Thuộc tính Giá trị


Name frmMessage
FormBorderStyle FixedToolWindow
Message.vb ShowIcon False
StartPosition CenterScreen
Text Thông báo
Name lblMessage
Lable1
Modifiers Public
PictureBox1 Image Question.bmp
Name btnCo
Button1 DialogResult Yes
Text Có
Name btnKhong
Button2 DialogResult No
Text Không

Bước 3: Viết Code

Mở cửa sổ code của Form1 và viết mã lệnh cho nút btnThoat như sau:

private void btnThoat_Click(object sender, EventArgs e)


{
frmMessage frm = new frmMessage();
frm.lblMessage.Text = "Bạn có muốn thoát không?";
if (frm.ShowDialog() ==
System.Windows.Forms.DialogResult.Yes)
Application.Exit();
}

Chú ý:

 Từ một form ta không thể tác động trực tiếp tới một form khác mà phải khai báo một biến
đại diện cho form muốn tác động và mọi thao tác đều được thực hiện trên biến này. Ví dụ từ

Bài giảng Cơ sở lập trình 2 59


form Form1 muốn hiển thị hoặc tác động tới các điều khiển trong form frmMessage ta khai
báo biến frm có kiểu là frmMessage như trên.

 Để hiển thị một Form khác ta gọi phương thức ShowDialog theo cú pháp sau:

TênbiếnForm.ShowDialog();

 Để truy cập tới thuộc tính của các điều khiển trong một Form khác ta phải thiết lập thuộc
tính Modifiers = Public cho điều khiển và thực hiện theo cú pháp sau:

TênbiếnForm.Tênđiềukhiển.Tênthuộctính = Giátrị;

 Khi ta thiết lập giá trị DialogResult cho một nút lệnh thì nếu người dùng kích chuột vào nút
lệnh đó cửa sổ Form chứa nút lệnh sẽ bị đóng lại và trả về giá trị của DialogResult tại nơi gọi
phương thức ShowDialog() để hiển thị Form đó.

 PictureBox là một điều khiển cho phép chứa các tệp ảnh có đuôi .bmp, .jpg… Trong máy
tính không có sẵn tệp ảnh Question.bmp mà ta phải tự tạo bằng ứng dụng Paint.

4. Một số điều khiển cơ bản khác

4.1. Nhóm – GroupBox

Nhóm có thể chứa các điều khiển khác và tạo thành các vùng làm việc độc lập trên một
Form.

GroupBox có một số thuộc tính thường dùng sau:

Name Tên nhóm, bắt đầu bởi tiếp đầu ngữ grb
BackColor Thiết lập mầu nền cho nhóm, nếu BackColor = Transparent
thì nhóm sẽ có mầu nền giống với mầu nền của Form.
BackgroundImage Thiết lập ảnh nền cho nhóm.
BackgroundImageLayout Thiết lập chế độ hiển thị ảnh nền của nhóm.
Enabled Nếu Enabled = False nhóm sẽ không hoạt động.
Font Xác lập kiểu chữ và cỡ chữ của tiêu đề nhóm.
ForeColor Xác lập mầu chữ của tiêu đề nhóm.
Locked Locked = True: khóa không cho phép dịch chuyển vị trí của
nhóm trên Form, ngược lại thì nhận giá trị False.
TabIndex Thứ tự truy cập của nhóm khi người dùng bấm phím Tab.
Text Thiết lập tiêu đề của nhóm.
Visible Visible = True: hiển thị nhóm, Visible = False: ẩn nhóm.

Bài giảng Cơ sở lập trình 2 60


4.2. Hộp đánh dấu – CheckBox

Hộp đánh dấu cho phép đồng thời không chọn, chọn một, hoặc chọn nhiều khả năng
trong một nhóm các lựa chọn.

4.2.1. Thuộc tính

Name Tên hộp CheckBox, bắt đầu bởi tiếp đầu ngữ chk
BackColor Thiết lập mầu nền cho hộp CheckBox.
BackgroundImage Thiết lập ảnh nền cho hộp CheckBox.
Checked Trả về giá trị của hộp CheckBox ứng với trạng thái của nó khi
tương tác với người sử dụng:
+ Checked =True: hộp CheckBox đang được chọn
+ Checked = False: hộp CheckBox không được chọn.
CheckState Thiết lập trạng thái cho hộp CheckBox:
+ CheckState = Checked: hộp CheckBox được chọn
+ CheckState = Unchecked: hộp CheckBox không được chọn.
Enabled Nếu Enabled = False hộp CheckBox sẽ không hoạt động.
Font Xác lập kiểu chữ và cỡ chữ của nội dung hộp CheckBox.
ForeColor Xác lập mầu chữ của nội dung hộp CheckBox.
Image Thiết lập ảnh hiển thị trên hộp CheckBox.
Locked Locked = True: khóa không cho phép dịch chuyển vị trí của hộp
CheckBox trên Form, ngược lại thì nhận giá trị False.
TabIndex Thứ tự truy cập khi người dùng bấm phím Tab.
Text Thiết lập nội dung của hộp CheckBox.
Visible Visible = True: hiển thị hộp CheckBox
Visible = False: ẩn hộp CheckBox.

4.2.2. Sự kiện

Click Được kích hoạt khi người dùng kích chuột vào hộp CheckBox.
GotFocus Được kích hoạt khi người dùng chuyển tiêu điểm tới hộp CheckBox.
LostFocus Được kích hoạt khi hộp CheckBox mất tiêu điểm.
CheckedChanged Được kích hoạt khi hộp CheckBox thay đổi trạng thái.

Bài giảng Cơ sở lập trình 2 61


4.3. Nút tuỳ chọn – RadioButton

Nút tuỳ chọn chỉ cho phép người dùng chọn một khả năng trong một nhóm các lựa
chọn.

4.3.1. Thuộc tính

Name Tên nút tuỳ chọn, bắt đầu bởi tiếp đầu ngữ rdo
BackColor Thiết lập mầu nền cho nút tùy chọn.
BackgroundImage Thiết lập ảnh nền cho nút tùy chọn.
Checked Trả về giá trị của nút tùy chọn khi tương tác với người sử dụng.
+ Checked = True: nút tùy chọn đang được chọn
+ Checked = False: nút tùy chọn không được chọn.
Enabled Nếu Enabled = False nút tuỳ chọn sẽ không hoạt động.
Font Xác lập kiểu chữ và cỡ chữ của nội dung nút tùy chọn.
ForeColor Xác lập mầu chữ của nội dung nút tùy chọn.
Image Thiết lập ảnh hiển thị trên nút tùy chọn.
Locked Locked = True: khóa không cho phép dịch chuyển vị trí của nút
tùy chọn trên Form, ngược lại thì nhận giá trị False.
TabIndex Thứ tự truy cập khi người dùng bấm phím Tab.
Text Thiết lập nội dung của nút tùy chọn.
Visible True: hiển thị nút tùy chọn, False: ẩn nút tùy chọn.

4.3.2. Sự kiện

Click Được kích hoạt khi người dùng kích chuột vào nút tuỳ chọn.
GotFocus Được kích hoạt khi người dùng chuyển tiêu điểm tới nút tuỳ chọn.
LostFocus Được kích hoạt khi nút tuỳ chọn mất tiêu điểm.
CheckedChanged Được kích hoạt khi nút tùy chọn thay đổi trạng thái.

Bài tập 6.

Lập chương trình nhập 2 số a và b, chọn và thực hiện các phép toán theo yêu cầu sau:

 Chỉ được nhập số cho a và b, không cho phép nhập dữ liệu vào hộp kết quả.

Bài giảng Cơ sở lập trình 2 62


 Các phép toán chỉ được thực hiện khi người dùng nhập đủ hai dữ liệu cho a và b. Trong phép
chia kiểm tra nếu b = 0 thì thông báo “Mẫu = 0” tại hộp Kết quả.

 Kích chọn phép toán nào thì thực hiện phép toán đó đối với a, b và lưu kết quả vào hộp Kết
quả.

 Nếu chọn hộp đánh dấu Max thì hiển thị “Max = <Giá trị max>” ngược lại chỉ hiển thị
“Max”. Thực hiện tương tự cho hộp đánh dấu Min.

Vào Microsoft Visual Studio 2010 tạo một dự án mới đặt tên là Calculation và thiết lập các thuộc
tính của các điều khiển như sau:

Điều khiển Thuộc tính Giá trị


Name frmCalculation
FormBorderStyle Fixed3D
Form1
Icon Chọn file ảnh có đuôi .ico bất kỳ
Text Program of Calculation
GroupBox1 Text Rỗng
GroupBox2 Text Phép toán
GroupBox3 Text So sánh
Lable1 Text Nhập a =

Bài giảng Cơ sở lập trình 2 63


Lable2 Text Nhập b =
Lable3 Text Kết quả =
TextBox1 Name txtNhapA
TextBox2 Name txtNhapB
TextBox3 Name txtKetqua
Name rdoCong
RadioButton1
Text Cộng
Name rdoTru
RadioButton2
Text Trừ
Name rdoNhan
RadioButton3
Text Nhân
Name rdoChia
RadioButton4
Text Chia
Name chkMax
CheckBox1
Text Max
Name chkMin
CheckBox2
Text Min
Name btnLamlai
Button1
Text Làm lại
Name btnThoat
Button2
Text Thoát

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

namespace Calculation
{
public partial class frmCalculation : Form
{
public frmCalculation()
{
InitializeComponent();
}

private void txtNhapa_KeyPress(object sender, KeyPressEventArgs


e)
{
if (((e.KeyChar >='0') && (e.KeyChar <='9'))||
(Convert.ToInt32(e.KeyChar)==8))

Bài giảng Cơ sở lập trình 2 64


e.Handled = false;
else
e.Handled = true;
}

private void txtNhapb_KeyPress(object sender, KeyPressEventArgs


e)
{
if (((e.KeyChar >='0') && (e.KeyChar <='9'))||
(Convert.ToInt32(e.KeyChar)==8))
e.Handled = false;
else
e.Handled = true;
}
private void rdoCong_Click(object sender, EventArgs e)
{
int a,b;
if (txtNhapa.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho a", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapa.Focus();
rdoCong.Checked = false;
return;
}
if (txtNhapb.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho b", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapb.Focus();
rdoCong.Checked = false;
return;
}
a = Convert.ToInt32(txtNhapa.Text);
b = Convert.ToInt32(txtNhapb.Text);
txtKetqua.Text = Convert.ToString(a + b);
txtNhapa.Enabled = false;
txtNhapb.Enabled = false;
}

private void rdoTru_Click(object sender, EventArgs e)


{
int a,b;

Bài giảng Cơ sở lập trình 2 65


if (txtNhapa.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho a", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapa.Focus();
rdoTru.Checked = false;
return;
}
if (txtNhapb.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho b", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapb.Focus();
rdoTru.Checked = false;
return;
}
a = Convert.ToInt32(txtNhapa.Text);
b = Convert.ToInt32(txtNhapb.Text);
txtKetqua.Text = Convert.ToString(a - b);
txtNhapa.Enabled = false;
txtNhapb.Enabled = false;
}

private void rdoNhan_Click(object sender, EventArgs e)


{
int a,b;
if (txtNhapa.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho a", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapa.Focus();
rdoNhan.Checked = false;
return;
}
if (txtNhapb.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho b", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapb.Focus();
rdoNhan.Checked = false;
return;

Bài giảng Cơ sở lập trình 2 66


}
a = Convert.ToInt32(txtNhapa.Text);
b = Convert.ToInt32(txtNhapb.Text);
txtKetqua.Text = Convert.ToString(a * b);
txtNhapa.Enabled = false;
txtNhapb.Enabled = false;
}

private void rdoChia_Click(object sender, EventArgs e)


{
int a,b;
if (txtNhapa.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho a", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapa.Focus();
rdoChia.Checked = false;
return;
}
if (txtNhapb.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho b", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapb.Focus();
rdoChia.Checked = false;
return;
}
a = Convert.ToInt32(txtNhapa.Text);
b = Convert.ToInt32(txtNhapb.Text);
if (b != 0)
txtKetqua.Text = Convert.ToString(a / b);
else
txtKetqua.Text = "Mẫu = 0";
txtNhapa.Enabled = false;
txtNhapb.Enabled = false;
}

private void chkMax_Click(object sender, EventArgs e)


{
int a,b;
if (txtNhapa.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho a", "Thông
báo",
Bài giảng Cơ sở lập trình 2 67
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapa.Focus();
chkMax.Checked = false;
return;
}
if (txtNhapb.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho b", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapb.Focus();
chkMax.Checked = false;
return;
}
a = Convert.ToInt32(txtNhapa.Text);
b = Convert.ToInt32(txtNhapb.Text);
if (chkMax.Checked == true)
{
if (a>b)
chkMax.Text = "Max= " + a.ToString ();
else
chkMax.Text = "Max= " + b.ToString ();
}
else
chkMax.Text = "Max";
txtNhapa.Enabled = false;
txtNhapb.Enabled = false;
}

private void chkMin_Click(object sender, EventArgs e)


{
int a,b;
if (txtNhapa.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho a", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapa.Focus();
chkMin.Checked = false;
return;
}
if (txtNhapb.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho b", "Thông
báo",

Bài giảng Cơ sở lập trình 2 68


MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapb.Focus();
chkMin.Checked = false;
return;
}
a = Convert.ToInt32(txtNhapa.Text);
b = Convert.ToInt32(txtNhapb.Text);
if (chkMin.Checked == true)
{
if (a<b)
chkMin.Text = "Min= " + a.ToString ();
else
chkMin.Text = "Min= " + b.ToString ();
}
else
chkMin.Text = "Min";
txtNhapa.Enabled = false;
txtNhapb.Enabled = false;
}

private void btnLamlai_Click(object sender, EventArgs e)


{
txtNhapa.Text = "";
txtNhapb.Text = "";
txtKetqua.Text = "";
rdoCong.Checked = false;
rdoTru.Checked = false;
rdoNhan.Checked = false;
rdoChia.Checked = false;
chkMax.Checked = false;
chkMax.Text = "Max";
chkMin.Checked = false;
chkMin.Text = "Min";
txtNhapa.Enabled = true;
txtNhapb.Enabled = true;
}

private void btnThoat_Click(object sender, EventArgs e)


{
if (MessageBox.Show("Bạn có muốn thoát không?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
System.Windows.Forms.DialogResult.Yes)
Application.Exit();
}
}
}
Bài giảng Cơ sở lập trình 2 69
Chú ý: trong đoạn mã lệnh trên tất cả các thủ tục: rdoCong_Click, rdoTru_Click, rdoNhan_Click,
rdoChia_Click, chkMax_Click, chkMin_Click đều phải kiểm tra người dùng nhập dữ liệu vào hai
hộp văn bản txtNhapA và txtNhapB. Để không phải viết lại đoạn mã lệnh kiểm tra nhiều lần ta viết
một hàm KiemtraAB như sau:

private bool KiemtraAB()


{
if (txtNhapa.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho a", "Thông
báo",MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapa.Focus();
return false;
}
if (txtNhapb.Text == "")
{
MessageBox.Show("Bạn phải nhập giá trị cho b", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNhapb.Focus();
return false;
}
return true;
}

private void rdoCong_Click(object sender, EventArgs e)


{
int a, b;
if (KiemtraAB() == false)
{
rdoCong.Checked = false;
}
else
{
a = Convert.ToInt32(txtNhapa.Text);
b = Convert.ToInt32(txtNhapb.Text);
txtKetqua.Text = Convert.ToString(a + b);
txtNhapa.Enabled = false;
txtNhapb.Enabled = false;
}
}
// Tương tự viết mã lệnh cho các thủ tục khác

Bài giảng Cơ sở lập trình 2 70


Bai 6: Lập chương trình thực hiện bài toán theo yêu cầu và giao diện như sau:

 Chỉ được phép nhập giá trị số cho Đơn giá và Số lượng, không cho phép nhập dữ liệu vào ô
Tổng tiền.

 Nếu Giảm giá được chọn thì hiển thị 2 điều khiển giảm giá 5% và 10%, ngược lại không
hiển thị 2 điều khiển này.

Hình 25. Giao diện bài tập 7

private void Form1_Load(object sender, EventArgs e)


{
rdo5.Visible = false;
rdo10.Visible = false;
}
private void chkGiamgia_Click(object sender, EventArgs e)
{
if (chkGiamgia.Checked == true)
{
rdo5.Visible = true;
rdo10.Visible = true;
rdo5.Checked = true;
}
else
{
rdo5.Visible = false;
rdo10.Visible = false;
}
}

private void rdo5_CheckedChanged(object sender, EventArgs e)

Bài giảng Cơ sở lập trình 2 71


{
txtTongtien.Text=””;
}

private void rdo10_CheckedChanged(object sender, EventArgs e)


{
txtTongtien.Text=””;
}

private void btnThuchien_Click(object sender, EventArgs e)


{
double sl, dg, tt=0;
// Kiểm tra người dùng phải nhập dữ liệu cho số lượng và đơn
giá
sl = Convert.ToDouble(txtSoluong.Text);
dg = Convert.ToDouble(txtDongia.Text);
if (chkGiamgia.Checked == true)
{
if (rdo5.Checked == true)
tt = sl * dg * 0.95;
else
tt = sl * dg * 0.9;
}
else
tt = sl * dg;
txtTongtien.Text = tt.ToString();
}

4.4. Hộp danh sách – ListBox

Hộp ListBox là một tập hợp các chuỗi ký tự được trình bày dưới dạng liệt kê thành từng
dòng trong một khung hình chữ nhật. Ta có thể chọn, bổ sung hoặc xoá một giá trị trong hộp danh
sách.

Khi hiển thị dữ liệu, nếu chiều ngang của Listbox nhỏ hơn độ dài các phần tử thì một phần dữ liệu sẽ
bị che khuất, còn nếu số phần tử của Listbox vượt quá chiều dài của Listbox thì Listbox tự động
cung cấp thanh cuốn dọc để cuộn tới các phần tử phía dưới.

4.4.1. Thuộc tính

Name Tên hộp ListBox, bắt đầu bởi tiếp đầu ngữ lst
BackColor Thiết lập mầu nền cho hộp danh sách.
DataSource Thiết lập nguồn dữ liệu cho ListBox
Enabled Nếu Enabled = False hộp danh sách sẽ không hoạt động.

Bài giảng Cơ sở lập trình 2 72


Font Xác lập kiểu chữ và cỡ chữ cho hộp danh sách.
ForeColor Xác lập mầu chữ cho hộp danh sách.
MultiColumn MultiColumn = True: cho phép hiển thị dữ liệu theo nhiều cột.
MultiColumn = False: chỉ cho phép hiển thị dữ liệu theo 1 cột.
ColumnWidth Thiết lập độ rộng cho mối cột trong ListBox.
Items Khởi tạo giá trị cho các phần tử của hộp danh sách trong thời gian thiết kế.
Khi chọn thuộc tính Items trong cửa sổ Properties, C# mở ra một hộp soạn
thảo cho phép người lập trình gõ vào giá trị các phần tử. Mỗi phần tử được
đặt trên một dòng riêng biệt, để xuống dòng nhấn Enter.
Items.Count Trả về tổng số phần tử của danh sách trong thời gian thi hành.
Items[n] Trả về nội dung phần tử thứ n của danh sách trong thời gian thi hành.
SelectedItem Tương tự như thuộc tính Items(n), nhưng chỉ có thể trả về nội dung của
hoặc Text phần tử hiện hành đang được chọn.
Locked Locked = True: khóa không cho phép dịch chuyển vị trí của hộp danh sách
trên Form, ngược lại thì nhận giá trị False.
SelectedIndex Trả về số thứ tự của phần tử đang được chọn trong danh sách, phần tử đầu
tiên có SelectedIndex = 0, nếu không có phần tử nào được chọn thì
SelectedIndex = -1
SelectionMode Quy định chế độ lựa chọn các phần tử trong hộp danh sách khi thực thi
chương trình. SelectionMode có 4 giá trị: None - không cho phép lựa chọn
các phần tử, One - cho phép chọn một phần tử, MultiSimple - cho phép lựa
chọn nhiều phần tử riêng biệt, MultiExtended - cho phép chọn một khối các
phần từ liền nhau.
SelectedItems Trả về tập các phần tử đang được chọn.
Sorted Nếu Sorted = True thì các phần tử trong danh sách được sắp xếp theo thứ tự
ABC.
TabIndex Thứ tự truy cập khi người dùng bấm phím Tab.
Visible True: hiển thị hộp danh sách, False: ẩn hộp danh sách.

4.4.2. Sự kiện

Click Được kích hoạt khi người dùng kích chuột vào hộp danh sách.
DoubleClick Được kích hoạt khi người dùng kích đúp chuột vào hộp danh sách.
GotFocus Được kích hoạt khi người dùng chuyển tiêu điểm tới hộp danh sách.
LostFocus Được kích hoạt khi hộp danh sách mất tiêu điểm.
SelectedIndex_ Được kích hoạt khi người dùng thay đổi trạng thái lựa chọn các dòng dữ
Changed liệu trong hộp văn bản.

Bài giảng Cơ sở lập trình 2 73


4.4.3. Phương thức 27.3

Add: dùng để bổ sung một phần tử cho hộp danh sách trong thời gian thi hành và thường được viết
trong thủ tục Form_Load. Cú pháp của phương thức này là:

ListName.Items.Add(Item);

Trong đó ListName là tên của hộp danh sách, Item là nội dung của phần tử ta muốn thêm vào hộp
danh sách.
Ví dụ, bổ sung phần tử có giá trị “Ha Noi” vào hộp danh sách lstQue ta thực hiện như sau:
lstQue.Items.Add(“Ha Noi”);

Remove: dùng để loại bỏ một phần tử của hộp danh sách theo nội dung trong thời gian thi hành. Cú
pháp của phương thức này là:

ListName.Items.Remove(Item);

Ví dụ, xóa phần tử có giá trị “Ha Noi” trong hộp danh sách lstQue ta viết như sau:
lstQue.Items.Remove(“Ha Noi”);

RemoveAt: dùng để loại bỏ một phần tử của hộp danh sách theo chỉ số trong thời gian thi hành. Cú
pháp của phương thức này là:

ListName.Items.RemoveAt(Index);

Ví dụ, xóa phần tử ở vị trí 1 trong hộp danh sách lstQue ta viết như sau:
lstQue.Items.RemoveAt(1);

Clear: dùng để loại bỏ tất cả các phần tử của hộp danh sách trong thời gian thi hành. Cú pháp của
phương thức này là:

ListName.Items.Clear();

Ví dụ, xóa tất cả các phần tử trong hộp danh sách lstQue ta viết như sau:
lstQue.Items.Clear();

Bài tập 7.

Viết chương trình minh hoạ các thao tác trên hộp Listbox theo yêu cầu sau:

 Nhập một tên nước vào hộp văn bản Nhập tên nước, chọn nút Thêm mới để thêm nước đó
vào hộp danh sách, chọn nút Tìm kiếm để xem nước đó đã có trong hộp danh sách chưa?

 Chọn nút Xóa để xoá một tên nước bất kỳ được chọn từ hộp danh sách.

 Chọn nút Thoát để thoát khỏi chương trình.


Bài giảng Cơ sở lập trình 2 74
Hình 26. Giao diện bài tập 8

Vào Microsoft Visual Studio 2010 tạo một dự án mới và thiết lập các thuộc tính của các điều
khiển như sau:

Điều khiển Thuộc tính Giá trị


Name frmTennuoc
FormBorderStyle Fixed3D
Form1
Icon Chọn file ảnh có đuôi .ico bất kỳ
Text Chuong trinh minh hoa Listbox
Lable1 Text Nhập tên nước
Lable2 Text Danh sách các nước
TextBox1 Name txtNuoc
ListBox1 Name lstNuoc
Name btnThemmoi
Button1
Text &Thêm mới
Name btnXoa
Button2
Text &Xóa
Name btnTimkiem
Button3
Text Tìm &kiếm
Name btnThoat
Button4
Text T&hoát
Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void Form1_Load(object sender, EventArgs e)


{

Bài giảng Cơ sở lập trình 2 75


txtNuoc.Focus();
btnTimkiem.Enabled = false;
btnXoa.Enabled = false;
}

private void btnThemmoi_Click(object sender, EventArgs e)


{
if (txtNuoc.Text == "")
{
MessageBox.Show("Bạn phải nhập tên nước", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNuoc.Focus();
return;
}
lstNuoc.Items.Add(txtNuoc.Text);
txtNuoc.Text = "";
txtNuoc.Focus();
btnXoa.Enabled = true;
btnTimkiem.Enabled = true;
}

private void btnXoa_Click(object sender, EventArgs e)


{
if (lstNuoc.Items.Count == 0)
{
MessageBox.Show("Không còn phần tử nào để xoá", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
btnXoa.Enabled = false;
btnTimkiem.Enabled = false;
return;
}
if (lstNuoc.SelectedIndex == -1)
{
MessageBox.Show("Bạn phải chọn một nước để xoá", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
Return;
}
if (MessageBox.Show("Bạn có muốn xoá không?", "Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
System.Windows.Forms.DialogResult.Yes)
lstNuoc.Items.RemoveAt(lstNuoc.SelectedIndex);
}

private void btnTimkiem_Click(object sender, EventArgs e)


{

Bài giảng Cơ sở lập trình 2 76


int i, index = 0, d = 0;
if (lstNuoc.Items.Count == 0)
{
MessageBox.Show("Không còn phần tử nào để tìm kiếm", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
btnXoa.Enabled = false;
btnTimkiem.Enabled = false;
return;
}
if (txtNuoc.Text == "")
{
MessageBox.Show("Bạn phải nhập tên nước để tìm kiếm", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNuoc.Focus();
return;
}
for (i = 0; i<= lstNuoc.Items.Count – 1; i++)
if (lstNuoc.Items[i].ToString().ToLower() ==
txtNuoc.Text.ToLower())
{
d = 1;
index = i;
break;
}
if (d == 1)
{
MessageBox.Show("Có tìm thấy nước " + txtNuoc.Text, "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
lstNuoc.SelectedIndex = index;
}
else
MessageBox.Show("Không tìm thấy nước " + txtNuoc.Text, "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtNuoc.Text = "";
txtNuoc.Focus();
}

Bài tập 8.

Viết chương trình minh hoạ các thao tác trên hộp Listbox theo giao diện và yêu cầu sau:

Bài giảng Cơ sở lập trình 2 77


Hình 27. Giao diện bài tập 9

Yêu cầu: + Nhập vào hộp danh sách 100 phần tử từ Items 1 đến Items 100.
+ Dữ liệu được hiển thị thành 4 cột trong một trang màn hình.
+ Người dùng có thể lựa chọn đồng thời một hoặc nhiều phần tử.
Vào Microsoft Visual Studio 2010 tạo một dự án mới, đặt một hộp danh sách lstDanhsach và một
nút lệnh btnKetqua với tiêu đề là Kết quả vào form Form1.

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void Form1_Load(object sender, EventArgs e)


{
int i;
// Cho phép hiển thị nhiều cột
lstDanhsach.MultiColumn = true ;
// Hiển thị 4 cột trong một trang
lstDanhsach.ColumnWidth = lstDanhsach.Width / 4;
// Cho phép chọn đồng thời nhiều phần tử
lstDanhsach.SelectionMode = SelectionMode.MultiSimple;
// Add dữ liệu vào hộp danh sách
for (i = 1 ; i <= 100; i++)
lstDanhsach.Items.Add("Items " + i);
}

private void btnKetqua_Click(object sender, EventArgs e)


{
string str = "";

Bài giảng Cơ sở lập trình 2 78


// Duyệt qua từng phần tử đã chọn
foreach (string Item in lstDanhsach.SelectedItems)
str = str + Item + ", ";
// Xóa dấu phẩy và dấu cách thừa ở cuối chuỗi str
str = str.Remove(str.Length - 2, 2);
MessageBox.Show("Bạn đã chọn phần tử " + str, "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}

4.5. Hộp lựa chọn – ComboBox

Hộp ComboBox cho phép lưu trữ và lựa chọn một mục dữ liệu trong một hộp danh
sách thả xuống.

4.5.1. Thuộc tính

Name Tên hộp ComboBox, bắt đầu bởi tiếp đầu ngữ cbo
BackColor Thiết lập mầu nền cho hộp Combo.
DataSource Thiết lập nguồn dữ liệu cho Combo.
DropDownStyle DropDown gồm một hộp văn bản cho phép người sử dụng có thể nhập
dữ liệu, kế bên có một mũi tên , nhấn vào đó sẽ xổ ra một danh sách
các mục dữ liệu cho phép người dùng chọn lựa.
Simple luôn hiển thị sẵn danh sách các mục dữ liệu bên dưới hộp văn
bản và cho phép người sử dụng có thể nhập dữ liệu vào hộp văn bản.
DropDownList tương tự như DropDown nhưng người sử dụng chỉ có
thể chọn các phần tử từ danh sách, khi gõ một ký tự vào hộp văn bản
thì danh sách sẽ cuộn đến các phần tử được bắt đầu bởi ký tự đó.
Enabled Nếu Enabled = False hộp Combo sẽ không hoạt động.
Font Xác lập kiểu chữ và cỡ chữ cho hộp Combo.
ForeColor Xác lập mầu chữ cho hộp Combo.
Items Khởi tạo giá trị các phần tử của hộp Combo trong thời gian thiết kế.
Items.Count Trả về tổng số phần tử của hộp Combo trong thời gian thi hành.
Items[n] Trả về nội dung phần tử thứ n của hộp Combo trong thời gian thi hành
SelectedItem Trả về nội dung của phần tử hiện hành đang được chọn.
hoặc Text
SelectedIndex Trả về số thứ tự của phần tử đang được chọn trong hộp Combo, phần
tử đầu tiên có SelectedIndex = 0, nếu không có phần tử nào được chọn
thì SelectedIndex = -1

Bài giảng Cơ sở lập trình 2 79


Locked True: không cho phép dịch chuyển vị trí của hộp Combo trên Form
Sorted True: các phần tử trong danh sách được sắp xếp theo thứ tự ABC.
TabIndex Thứ tự truy cập khi người dùng bấm phím Tab.
Visible True: hiển thị hộp Combo, False: ẩn hộp Combo.

4.5.2. Sự kiện

Click Được kích hoạt khi người dùng kích chuột vào hộp Combo.
DoubleClick Được kích hoạt khi người dùng kích đúp chuột vào hộp Combo.
GotFocus Được kích hoạt khi người dùng chuyển tiêu điểm tới hộp Combo.
LostFocus Được kích hoạt khi hộp Combo mất tiêu điểm.
SelectedIndex_ Được kích hoạt khi người dùng thay đổi trạng thái lựa chọn các dòng
Changed dữ liệu trong hộp văn bản.
TextChanged Được kích hoạt khi người dùng nhập, sửa, xóa dữ liệu tại vùng văn
bản của hộp Combo hoặc khi ta thay đổi thuộc tính Text của hộp
Combo từ mã lệnh.
DropDown Chỉ xảy ra đối với hộp Combo DropDown và DropDownList, sự kiện
này được gọi ngay sau khi người dùng nhấp mũi tên để thả hộp danh
sách xuống (phím tắt Alt+). Vì thế sự kiện này chủ yếu được sử dụng
để nhập dữ liệu cho các phần tử của hộp Combo.

4.5.3. Phương thức

Add: dùng để bổ sung một phần tử cho hộp Combo trong thời gian thi hành và thường được viết
trong thủ tục Form_Load. Cú pháp của phương thức này là:

ComboName.Items.Add(Item);

Trong đó ComboName là tên của hộp Combo, Item là nội dung của phần tử ta muốn thêm vào hộp
Combo.

Ví dụ, bổ sung phần tử có giá trị “Ha Noi” vào hộp Combo cboQue ta thực hiện như sau:

cboQue.Items.Add(“Ha Noi”);

Remove: dùng để loại bỏ một phần tử của danh sách theo nội dung trong thời gian thi hành. Cú pháp
của phương thức này là:

ComboName.Items.Remove(Item);

Ví dụ, xóa phần tử có giá trị “Ha Noi” trong hộp Combo cboQue ta viết như sau:

Bài giảng Cơ sở lập trình 2 80


cboQue.Items.Remove(“Ha Noi”);

RemoveAt: dùng để loại bỏ một phần tử của hộp Combo theo chỉ số trong thời gian thi hành. Cú
pháp của phương thức này là:

ComboName.Items.RemoveAt(Index);

Ví dụ, xóa phần tử ở vị trí 1 trong hộp Combo cboQue ta viết như sau:

cboQue.Items.RemoveAt(1);

Clear: dùng để loại bỏ tất cả các phần tử của hộp Combo trong thời gian thi hành. Cú pháp của
phương thức này là:

ComboName.Items.Clear();

Ví dụ, xóa tất cả các phần tử trong hộp Combo cboQue ta viết như sau:

cboQue.Items.Clear();

Ví dụ: Giả sử có hộp combo cboQue, để nhập dữ liệu cho nó ta có 2 cách sau:

Cách 1: Cập nhập bằng thủ tục Form_Load:

private void Form1_Load(object sender, EventArgs e)


{
cboQue.Items.Add("Hà Nội");
cboQue.Items.Add("Nam Định");
cboQue.Items.Add("Đà Lạt");
}

Cách 2: Cập nhập bằng sự kiện DropDown:

private void cboQue_DropDown(object sender, EventArgs e)


{
cboQue.Items.Clear();
cboQue.Items.Add("Hà Nội");
cboQue.Items.Add("Nam Định");
cboQue.Items.Add("Đà Lạt");
}

Bài tập 9.

Lấy danh sách các thư mục có trong thư mục “D:\Baigiang” lưu vào hộp Combo thông qua thuộc
tính DataSource.

Bài giảng Cơ sở lập trình 2 81


Hình 28. Giao diện bài tập 10

Vào Microsoft Visual Studio 2010 tạo một dự án mới, đặt một hộp combo cboThumuc vào form
frmCombo.

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void frmCombo_Load(object sender, EventArgs e)


{
string[] Folder;
Folder = System.IO.Directory.GetDirectories("D:\\Baigiang");
cboThumuc.DataSource = Folder;
}

Bài tập 10.

Lập chương trình thực hiện các công việc thay đổi Font chữ theo giao diện dưới đây:

Hình 29. Giao diện bài tập 11


Bài giảng Cơ sở lập trình 2 82
Gợi ý: Cú pháp thay đổi kiểu Font chữ:

<TênĐiềukhiển>.Font = new Font("TênFont", Cỡchữ) ;

Cú pháp thay đổi hiệu ứng font chữ:

<TênĐiềukhiển>.Font = new Font(<TênĐiềukhiển>.Font, FontStyle.HiệuỨng) ;

Trong đó Hiệu ứng có thể nhận các giá trị: Bold, Regular, Italic, UnderLine, Strikeout. Để kết hợp
các hiệu ứng ta dùng toán tử |, để loại trừ các hiệu ứng ta dùng toán tử ^, để lấy hiệu ứng của điều
khiển ta dùng cú pháp <Tênđiềukhiển>.Font.Style

Cú pháp thay đổi mầu chữ:

<TênĐiềukhiển>.ForeColor = Color.Màu ;

Bài tập 11.


Lập chương trình ghép tên nước và tên thành phố theo giao diện và yêu cầu dưới đây:

Hình 30. Giao diện bài tập 12

Bài giảng Cơ sở lập trình 2 83


 Viết thủ tục EmptyOption() bỏ chọn tất cả các RadioButton tên thành phố.

 Khi kích chọn vào một nước, giả sử France thì xuất hiện dòng thông báo: “Hãy chọn thành
phố cho France” và gọi thủ tục EmptyOption

 Khi kích chọn một thành phố, nếu đúng là thành phố của tên nước đã chọn thì xuất hiện dòng
thông báo, ví dụ: “Chúc mừng bạn, thủ đô của France là Paris”, ngược lại thông báo, ví dụ:
“Bạn sai rồi, thủ đô của France không phải là London”

Bài tập 12.

Lập chương trình thực hiện các công việc theo giao diện và yêu cầu dưới đây:

 Chương trình có một Form bán hàng trực tuyến, danh sách các mặt hàng được hiển thị sẵn
trong hộp Listbox hoặc CheckedListBox “Danh sách các mặt hàng”

 Để mua hàng người dùng kích đúp vào mặt hàng cần mua trong “Danh sách các mặt hàng”,
mặt hàng được chọn sẽ được hiển thị vào trong “Hàng đặt mua”.

Hình 31. Giao diện bài tập 13

Bài giảng Cơ sở lập trình 2 84


Chú ý: Khi mua hàng phải kiểm tra nếu mặt hàng này đã được mua thì dùng hộp thoại thông báo đã
chọn mặt hàng đó và không được mua mặt hàng đó nữa.

Người dùng có thể xoá mặt hàng trong số các mặt hàng đã chọn bằng cách kích đúp vào mặt hàng
cần xoá, trước khi xoá phải hỏi lại người dùng có muốn xoá hay không?

 Khi kích chuột vào nút “Đồng ý” kiểm tra người dùng phải nhập đầy đủ thông tin và hiện
thông báo gồm các thông tin: Tên khách, Địa chỉ, Danh sách các mặt hàng đã mua, Phương
thức thanh toán và Hình thức liên lạc. Chú ý: để xuống một dòng mới ta dùng phương thức
System.Environment.NewLine

4.6. Điều khiển CheckedListBox

Điều khiển CheckedListBox cho phép lưu trữ và hiển thị các mục dữ liệu theo
dòng và có một hộp CheckBox ở đầu dòng.

Điều khiển CheckedListBox có tiếp đầu ngữ là clb và có các thuộc tính, sự kiện, phương thức tương
tự như điều khiển ListBox.

Ngoài ra nó có thêm một số thuộc tính và sự kiện khác như sau:

Bài giảng Cơ sở lập trình 2 85


CheckedItems Thuộc tính này trả về tập các phần tử được Check.
ItemCheck Được kích hoạt khi người dùng kích đúp chuột vào hộp Combo.

Bài tập 13.

Tạo một form mới đặt tên là frmCheckListBox, đặt lên form hộp điều khiển CheckedListBox
clbSach và nút lệnh btnKetqua.

Viết chương trình hiển thị 10 loại sách được chia thành 2 cột vào trong hộp clbSach. Khi người
dùng đánh dấu vào hộp CheckBox của từng phần tử, sẽ xuất hiện hộp thông báo tên quyển sách
tương ứng với phần tử đó, như hình minh họa sau:

Hình 32. Giao diện bài tập 14

Khi người dùng kích chọn nút Kết quả sẽ xuất hiện hộp thoại thông báo tên tất cả các quyển sách
người dùng đã chọn.

Bài giảng Cơ sở lập trình 2 86


Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void Form1_Load(object sender, EventArgs e)


{
clbSach.Items.Add("Visual Basic.NET 2005");
clbSach.Items.Add("Visual C#.NET 2005");
clbSach.Items.Add("Lập trình Oracle");
clbSach.Items.Add("Lập trình Cơ sở dữ liệu");
clbSach.Items.Add("Lập trình C");
clbSach.Items.Add("Lập trình Pascal");
clbSach.Items.Add("Phân tích thiết kế hướng đối tượng");
clbSach.Items.Add("Lập trình C For Win");
clbSach.Items.Add("Nhập môn Xử lý ảnh");
clbSach.Items.Add("Đồ họa máy tính");
clbSach.MultiColumn = true;
clbSach.ColumnWidth = clbSach.Width / 2;
}

private void btnKetqua_Click(object sender, EventArgs e)


{
string str="";
// Duyệt qua từng phần tử đã chọn
foreach (string item in clbSach.CheckedItems)
str = str + item + ", ";
// Xóa dấu phẩy và dấu cách thừa ở cuối chuỗi str
str = str.Remove(str.Length - 2, 2);
MessageBox.Show("Bạn đã chọn sách " + str, "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}

private void clbSach_ItemCheck(object sender, ItemCheckEventArgs


e)
{
// Dựa vào thuộc tính NewValue của đối e để biết trạng thái
của hộp Checkbox
if (e.NewValue == CheckState.Checked)
MessageBox.Show("Bạn đã chọn sách " + clbSach.Text,
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}

4.7. Điều khiển NumericUpDown

Bài giảng Cơ sở lập trình 2 87


Điều khiển NumericUpDown cho phép người dùng lựa chọn một giá trị số trong
một khoảng giá trị với một bước nhảy xác định.

4.7.1. Thuộc tính

Name Tên điều khiển NumericUpDown, bắt đầu bởi tiếp đầu ngữ nud
Increment Giá trị của bước nhảy.
Maximum Cận trên của khoảng giá trị.
Minimum Cận dưới của khoảng giá trị.
Value Giá trị hiện tại của điều khiển NumericUpDown.

4.7.2. Sự kiện

ValueChanged Được kích hoạt khi người dùng thay đổi giá trị của điều khiển.

Bài tập 14.

Dùng điều khiển NumericUpDown để giải phương trình bậc hai đủ:

ax2 + bx + c = 0 (a, b, c có giá trị trong đoạn [-100, 100])

Hình 33. Giao diện bài tập 15

Vào Microsoft Visual Studio 2010 tạo một dự án mới, đặt tên form là frmPTBH và đặt vào form các
điều khiển sau:

 Ba điều khiển NumericUpDown có tên nudNhapA, nudNhapB, nudNhapC. Các thuộc tính:
Maximum = 100, Minimum = -100, Increment = 1.

Bài giảng Cơ sở lập trình 2 88


 Ba hộp Textbox có tên txtKetqua, txtX1, txtX2. Các thuộc tính: ReadOnly = True, BackColor
=White. Hộp kết quả có thuộc tính Multiline = True.

 Hai nút lệnh btnGiaiPTBH, btnThoat và các nhãn Label…

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void btnGiaiPTBH_Click(object sender, EventArgs e)


{
PTBH(Convert.ToInt32(nudNhapA.Value),
Convert.ToInt32(nudNhapB.Value),
Convert.ToInt32(nudNhapC.Value));
}

private void PTBH(int a, int b, int c)


{
double delta ,x1,x2;
if ((a == 0) || (b == 0) || (c == 0))
{
txtKetqua.Text = "Không giải vì không phải phương trình
bậc hai đủ";
btnGiaiPTBH.Enabled = false ;
return;
}
delta = b * b - 4 * a * c;
if (delta < 0)
{
txtKetqua.Text = txtKetqua.Text + "Phương trình vô
nghiệm";
btnGiaiPTBH.Enabled = false;
return;
}
if (delta == 0)
{
x1 = Math.Round ((-b / (2.0 * a)), 2);
txtKetqua.Text = txtKetqua.Text + "Phương trình có nghiệm
kép";
txtX1.Text = Convert.ToString(x1);
txtX2.Text = Convert.ToString(x1);
btnGiaiPTBH.Enabled = false;
return;
}
x1 = Math.Round((-b + Math.Sqrt(delta)) / (2 * a), 2);
x2 = Math.Round((-b - Math.Sqrt(delta)) / (2 * a), 2);
txtKetqua.Text = txtKetqua.Text + "Phương trình có 2 nghiệm
phân biệt";
Bài giảng Cơ sở lập trình 2 89
txtX1.Text = Convert.ToString(x1);
txtX2.Text = Convert.ToString(x2);
btnGiaiPTBH.Enabled = false;
}

private void EmptyText()


{
txtX1.Text = "";
txtX2.Text = "";
}

private void nudNhapA_ValueChanged(object sender, EventArgs e)


{
txtKetqua.Text = "A=" + nudNhapA.Value +
System.Environment.NewLine;
txtKetqua.Text = txtKetqua.Text + "B=" + nudNhapB.Value +
System.Environment.NewLine;
txtKetqua.Text = txtKetqua.Text + "C=" + nudNhapC.Value +
System.Environment.NewLine;
btnGiaiPTBH.Enabled = true;
EmptyText();
}

// Thực hiện tương tự cho nudNhapB_ValueChanged và


nudNhapC_ValueChanged

4.8. Thanh cuộn HScrollBar và VScrollBar

Thanh cuộn ngang HScrollBar và thanh cuộn dọc VScrollBar cho phép
người dùng lựa chọn một giá trị số trong một khoảng giá trị xác định.

4.8.1. Thuộc tính

Name Tên thanh cuộn, bắt đầu bởi tiếp đầu ngữ hsb và vsb.
Minimum Số nguyên xác định giá trị nhỏ nhất cho thanh cuộn.
Maximum Số nguyên xác định giá trị lớn nhất cho thanh cuộn.
Value Cho biết giá trị hiện thời của thanh cuộn.
LargeChange Chỉ ra mức độ thay đổi của thuộc tính Value khi người dùng nhấn chuột
trên thanh cuộn.
SmallChange Chỉ ra mức độ thay đổi của thuộc tính Value khi người dùng nhấn chuột
vào các mũi tên trên thanh cuộn (giá trị mặc định = 1).

4.8.2. Sự kiện
Bài giảng Cơ sở lập trình 2 90
ValueChanged Được kích hoạt khi người dùng thay đổi giá trị của thanh cuộn.
Scroll Xảy ra khi người dùng kéo rê chuột hoặc kích chuột vào các mũi tên
trên thanh cuộn.

Bài tập 15.

Dùng thanh cuộn HScrollBar để thay đổi mầu nền cho Form.

Hình 34. Giao diện bài tập 16

Vào Microsoft Visual Studio 2010 tạo một dự án mới, đặt tên form là frmMaunen và đặt vào form
các điều khiển sau:

 Ba điều khiển HScrollBar có tên hsbRed, hsbGreen, hsbBlue. Các thuộc tính: Maximum =
255, Minimum = 0, LargeChange = 10, SmallChange = 1.

 Ba nhãn Label đặt ở bên phải các thanh cuộn có tên lblRed, lblGreen, lblBlue để lưu giá trị
hiện thời của các thanh cuộn tương ứng.

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void hsbRed_ValueChanged(object sender, EventArgs e)


{
this.BackColor = Color.FromArgb(hsbRed.Value, hsbGreen.Value,
hsbBlue.Value);
lblRed.Text = hsbRed.Value.ToString ();
}

private void hsbGreen_ValueChanged(object sender, EventArgs e)


{
this.BackColor = Color.FromArgb(hsbRed.Value, hsbGreen.Value,
hsbBlue.Value);
lblGreen.Text = hsbGreen.Value.ToString();

Bài giảng Cơ sở lập trình 2 91


}

private void hsbBlue_ValueChanged(object sender, EventArgs e)


{
this.BackColor = Color.FromArgb(hsbRed.Value, hsbGreen.Value,
hsbBlue.Value);
lblBlue.Text = hsbBlue.Value.ToString();
}

Chú ý: Color.FromArgb(Red, Green, Blue) cho phép tạo một màu bằng cách kết hợp các giá trị của
3 mầu cơ bản Red, Green, Blue. Ba mầu này nhận các giá trị từ 0 đến 255.

4.9. Điều khiển Timer

Điều khiển định thời gian Timer cho phép thực thi lại một hành động sau một khoảng thời
gian xác định.

Khi ta đưa điều khiển Timer vào Form nó không xuất hiện trên Form mà xuất hiện như một biểu
tượng ở trên một khay đặt ở cuối cửa sổ thiết kế. Khi chạy chương trình điều khiển Timer cũng
không xuất hiện.

4.9.1. Thuộc tính

Name Tên điều khiển Timer, bắt đầu bởi tiếp đầu ngữ tmr
Interval = n là chu kỳ thực hiện sự kiện Tick của điều khiển Timer.
n là số nguyên, được tính bằng mili giây và có giá trị >0
Enabled Enabled = True: cho phép điều khiển Timer hoạt động
Enabled = False: không cho phép điều khiển Timer hoạt động.

4.9.2. Sự kiện

Tick Sự kiện này được kích hoạt sau mỗi chu kỳ Interval.

4.9.3. Phương thức

Start: kích hoạt điều khiển Timer, phương thức này tương tự thuộc tính Enabled = true.

Cú pháp:

TimerName.Start();

Stop: dừng điều khiển Timer, phương thức này tương đương với thuộc tính Enabled = false.

Cú pháp:

Bài giảng Cơ sở lập trình 2 92


TimerName.Stop();

Bài tập 16.

Viết chương trình mô tả sự chuyển động của mặt trăng gồm 8 hình ảnh đặt trong thư mục D:\Icons\
Moon như sau:

Hình 35. Giao diện bài tập 17

Vào Microsoft Visual Studio 2010 tạo một dự án mới và thiết lập các thuộc tính của các điều
khiển như sau:

Điều khiển Name Text Image Visible


Form1 frmMoon Trang chuyen dong
PictureBox1 pic1 Moon01.bmp False
PictureBox2 pic2 Moon02.bmp False
PictureBox3 pic3 Moon03.bmp False
PictureBox4 pic4 Moon04.bmp False
PictureBox5 pic5 Moon05.bmp False
PictureBox6 pic6 Moon06.bmp False
PictureBox7 pic7 Moon07.bmp False
PictureBox8 pic8 Moon08.bmp False
PictureBox9 pic True
Button1 btnStart Start True
Button2 btnExit Exit True
Timer tmrTimer Enabled = True và Interval = 250

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

Bài giảng Cơ sở lập trình 2 93


public partial class frmMoon : Form
{
int Coquay;
int Curmoon;

public frmMoon()
{
InitializeComponent();
}

private void frmMoon_Load(object sender, EventArgs e)


{
Coquay = 0 ; // Không cho phép quay
Curmoon = 1 ; // Chỉ số ảnh hiện hành
}

private void btnStart_Click(object sender, EventArgs e)


{
if (Coquay ==0)
{
Coquay = 1;
btnStart.Text = "Stop";
}
else
{
Coquay = 0;
btnStart.Text = "Start";
}
}

private void Hienthi (int index)


{
switch (index)
{
case 1:
pic.Image = pic1.Image;
break;
case 2:
pic.Image = pic2.Image;
break;
case 3:
pic.Image = pic3.Image;
break;
case 4:
pic.Image = pic4.Image;

Bài giảng Cơ sở lập trình 2 94


break;
case 5:
pic.Image = pic5.Image;
break;
case 6:
pic.Image = pic6.Image;
break;
case 7:
pic.Image = pic7.Image;
break;
case 8:
pic.Image = pic8.Image;
break;
}
}

private void tmrTimer_Tick(object sender, EventArgs e)


{
if (Coquay == 1 )
Hienthi(Curmoon);
Curmoon = Curmoon + 1;
if (Curmoon == 9)
Curmoon = 1;
}
}

Bài tập 17.

Viết chương trình tạo dòng chữ “Chào mừng bạn” chuyển động từ trái qua phải màn hình, khi gặp
mép màn hình thì chuyển động ngược lại từ phải qua trái. Cứ lặp lại như vậy cho đến khi kết thúc
chương trình.

Hình 36. Giao diện bài tập 18

Vào Microsoft Visual Studio 2010 tạo một dự án mới và thiết lập các thuộc tính của các điều
khiển như sau:

Điều khiển Name Text

Bài giảng Cơ sở lập trình 2 95


Form1 frmMove Dong chu chuyen dong
Label1 lblMove Chào mừng bạn
Timer tmrTimer Enabled = True và Interval = 200

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

public partial class frmMove : Form


{
bool Kt; //Kt=true chuyen dong sang phai, Kt=false chuyen
dong sang trai
public frmMove()
{
InitializeComponent();
}

private void frmMove_Load(object sender, EventArgs e)


{
Kt = true;
}

private void tmrTimer_Tick(object sender, EventArgs e)


{
if (Kt)
{
if (lblMove.Left + lblMove.Width < this.Width)
lblMove.Left = lblMove.Left + 13;
else
Kt = false;
}
if (!Kt)
{
if (lblMove.Left > 0 )
lblMove.Left = lblMove.Left - 13;
else
Kt = true;
}
}
}

4.10. Điều khiển RichTextBox

Bài giảng Cơ sở lập trình 2 96


Điều khiển RichTextBox cho phép tạo và hiển thị các tệp văn bản có phần mở rộng
‘.rtf’. RichTextBox khác với TextBox ở chỗ nó cho phép hiển thị màu sắc, loại Font, cỡ chữ… khác
nhau cho từng đoạn khác nhau trong văn bản.

Để tạo một tệp có phần mở rộng .rtf ta có thể sử dụng trình soạn thảo Word và lưu tệp – Save As
theo định dạng Rich TextFormat (*.rtf)

Điều khiển RichTextBox có tiếp đầu ngữ là rtb và có 2 phương thức cơ bản sau:

LoadFile: nạp nội dung một tệp .rtf vào RichTextBox.

Ví dụ nạp nội dung tệp Bai1.rtf trong ổ D vào hộp RichTextBox rtbBai1:

rtbBai1.LoadFile("D:\\Bai1.rtf", RichTextBoxStreamType.RichText);

SaveFile: lưu nội dung trong hộp RichTextBox vào một tệp có phần mở rộng .rtf.

Ví dụ lưu nội dung của hộp RichTextBox rtbBai1 vào tệp Bai2.rtf trong ổ D: (nếu tệp Bai2.rtf chưa
tồn tại thì sẽ được tạo mới)

rtbBai1.SaveFile("D:\\Bai2.rtf", RichTextBoxStreamType.RichText);

4.11. Điều khiển DateTimePicker

Điều khiển DateTimePicker cho phép người dùng chọn thời gian dưới dạng
lịch biểu, ta có thể duyệt theo từng ngày hoặc từng tháng.

Thuộc tính:

Name Tên điều khiển DateTimePicker, bắt đầu bởi tiếp đầu ngữ dtp
Format Định dạng kiểu hiển thị của thời gian, Ngày tháng thường chọn giá trị Short
Values Trả về giá trị hiện thời của điều khiển DateTimePicker

Hình 37. Giao diện điều khiển DateTimePicker

Bài giảng Cơ sở lập trình 2 97


4.12. Điều khiển Windows Media Player

Điều khiển Windows Media Player cho phép người dùng lập trình để nghe nhạc và xem phim với
các chức năng tương tự như Windows Media Player trong Windows.

Điều khiển Windows Media Player không có sẵn trên hộp công cụ Toolbox, để đưa điều khiển này
vào hộp công cụ ta kích chuột phải tại tab Common Controls, chọn Choose Items… kết quả xuất
hiện hộp hội thoại Choose Toolbox Items:

Hình 38. Kích hoạt điều khiển Windows Media Player

Chọn tab COM Components, kích chọn Windows Media Player rồi chọn OK.

Kết quả xuất hiện điều khiển trên hộp công cụ.

Bài tập 18.

Viết chương trình nghe nhạc MP3 theo yêu cầu và giao diện dưới đây:

Bài giảng Cơ sở lập trình 2 98


Hình 39. Giao diện bài tập 19

Khi người dùng kích chọn một bài hát trong Listbox danh sách các bài hát thì:

 Lời bài hát sẽ được hiển thị tại hộp RichTextBox.

 Điều khiển Windows Media Player sẽ phát bài hát đó.

Bài giảng Cơ sở lập trình 2 99


Vào Microsoft Visual Studio 2010 tạo một dự án mới đặt tên là Music, lưu vào thư mục D:\
Baigiang\C#HVNH\Baitap và thiết lập các thuộc tính cho các điều khiển của dự án như sau:

Điều khiển Name Text


Form1 frmMusic Nhung bai hat hay
Listbox1 lstDanhsach
RichTextBox1 rtbMusic
axWindowsMediaPlayer1 wmpMusic
Button1 btnClose Close

Ngoài ra ta phải chuẩn bị các tệp nhạc .mp3 và tệp lời .rtf đặt trong thư mục Nhac_Loi và lưu vào
thư mục Music của dự án.

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

using WMPLib; //Để làm việc với các hàm của Windows Media Player

Bài giảng Cơ sở lập trình 2 100


CHƯƠNG 5.
CÁC HỘP THOẠI THÔNG DỤNG

Chúng ta thấy trong hầu hết các ứng dụng của Windows đều có các hộp thoại Open để mở tập tin,
Save để lưu các tập tin hoặc các hộp thoại Color để chọn màu, Font để chọn phông chữ... các hộp
thoại này gọi là các hộp thoại thông dụng - Common Dialog.

Để sử dụng các hộp thoại thông dụng ta dùng các lớp đối tượng .NET trong thư viện System.IO bao
gồm 5 lớp tương ứng với 5 hộp hội thoại cơ bản như sau:

Hộp thoại Lớp đối tượng


Mở tập tin – Open File OpenFileDialog()
Lưu tập tin – Save File SaveFileDialog()
Chọn màu – Color ColorDialog()
Chọn phông – Font FontDialog()
In ấn – Print PrintDialog()

1. Hộp hội thoại Open File

File word |*.doc | richtexbox |*.rtf

Các thuộc tính và phương thức quan trọng của hộp hội thoại OpenFile:

Thuộc tính Chức năng


FileName Cung cấp tên và đường dẫn của tập tin đã chọn.
Filter Xác định danh sách các bộ lọc tập tin mà hộp hội thoại sẽ hiển thị.Ví
dụ: “Text|*.txt|Icons|*.ico|All files|*.*” (không được chứa dấu cách)
FilterIndex Chỉ ra bộ lọc tập tin mặc định, giả sử có 3 bộ lọc (*.com), (*.exe) và
(*.ico) nếu FilterIndex = 2 thì hộp thoại sẽ hiển thị sẵn bộ lọc (*.exe)
InitialDirectory Xác định thư mục mặc định cho hộp hội thoại khi vừa được gọi.
Multiselect Multiselect = True: cho phép người dùng chọn đồng thời nhiều file.
FileNames Cung cấp tên và đường dẫn của các tập tin đã chọn.
Title Xác định tiêu đề của hộp hội thoại.
OpenFile Mở nội dung File đã được chọn (ReadOnly).

Bài tập 19.

Bài giảng Cơ sở lập trình 2 101


Viết chương trình cho phép tìm kiếm các hình ảnh để hiển thị lên form.

Hình 40. Giao diện bài tập 20

Vào Microsoft Visual Studio 2010 tạo dự án mới đặt tên là OpenDialog lưu vào thư mục D:\
Baigiang\C#HVNH\Baitap và thiết lập thuộc tính của các điều khiển như sau:

Điều khiển Name Text


Form1 frmPicture Hien thi hinh anh
PictureBox picAnh
Button1 btnOpen Open

Chạy chương trình, kích chọn nút lệnh Open sẽ xuất hiện hộp thoại sau:

Bài giảng Cơ sở lập trình 2 102


Chọn một ảnh bất kỳ muốn hiển thị sau đó kích chọn Open, ảnh sẽ được hiển thị lên điều khiển
PictureBox trên form.

Trong trường hợp người dùng chọn Cancel sẽ xuất hiện thông báo: “You clicked Cancel!”

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void btnOpen_Click(object sender, EventArgs e)


{
OpenFileDialog dlgOpen = new OpenFileDialog();
dlgOpen.Filter = "Bitmap(*.bmp)|*.bmp|Gif(*.gif) |*.gif|All
files(*.*)|*.*";
dlgOpen.InitialDirectory = "D:\\Baigiang";
dlgOpen.FilterIndex = 2;
dlgOpen.Title = "Chon hinh anh de hien thi";
if (dlgOpen.ShowDialog() == DialogResult.OK)
picAnh.Image = Image.FromFile(dlgOpen.FileName);
else
MessageBox.Show("You clicked Cancel" , "Open Dialog",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}

2. Hộp thoại SaveFile và luồng FileStream

2.1. Hộp thoại SaveFile

Các thuộc tính và phương thức của hộp hội thoại SaveFile:

Thuộc tính Chức năng


FileName Cung cấp tên và đường dẫn của tập tin đã chọn.
Filter Xác định danh sách các bộ lọc tập tin mà hộp hội thoại sẽ hiển thị, ví
dụ: “Text|*.txt|Icons|*.ico|All files|*.*”
FilterIndex Chỉ ra bộ lọc tập tin mặc định, giả sử có 3 bộ lọc (*.com), (*.exe) và
(*.ico) nếu FilterIndex = 2 thì hộp thoại sẽ hiển thị sẵn bộ lọc (*.exe)
AddExtension = True tự động thêm phần mở rộng hiện hành vào tên tệp mà người
dùng chọn nếu người dùng không chỉ rõ phần mở rộng của tên tệp.
DefaultExt Cung cấp phần mở rộng mặc định cho tên tệp, nếu người dùng không
chỉ rõ phần mở rộng của tên tệp, ví dụ: “.doc”
InitialDirectory Xác định thư mục mặc định cho hộp hội thoại khi vừa được gọi.
Title Xác định tiêu đề của hộp hội thoại.

Bài giảng Cơ sở lập trình 2 103


2.2. Luồng FileStream

Với một file dữ liệu có kiểu bất kỳ đều được coi là một luồng dữ liệu, ta có thể mở một luồng dữ
liệu để đọc thông tin từ file hoặc ghi thông tin vào file sau đó đóng luồng lại.

Luồng ghi dữ liệu - StreamWriter

 Mở luồng để ghi file:


StreamWriter Tenluong = new StreamWriter(Tenfile);
 Ghi từng dòng dữ liệu vào file:
Tenluong.WriteLine(“Noidung”);
 Ghi tất cả dữ liệu vào file:
Tenluong.Write(“Noidung”);

Luồng đọc dữ liệu - StreamReader

 Mở luồng để đọc file:


StreamReader Tenluong = new StreamReader(Tenfile);
 Đọc từng dòng dữ liệu của file: ta dùng vòng lặp với số lần lặp không xác định để đọc từng
dòng dữ liệu, nếu đọc thành công thì trả về chuỗi chứa dữ liệu đọc được, nếu đến cuối file thì
trả về Nothing.
Noidung = Tenluong.ReadLine();
 Đọc tất cả dữ liệu của file lưu vào một biến:
Noidung = Tenluong.ReadToEnd();
 Đóng luồng:
Tenluong.Close();

Chú ý: StreamWriter và StreamReader nằm trong lớp System.IO

Bài tập 20.

Viết chương trình cho phép lưu nội dung của hộp Textbox vào một File trên máy tính, với giao diện
và yêu cầu như sau:

Bài giảng Cơ sở lập trình 2 104


Hình 41. Giao diện bài tập 21

Kích chọn nút Save xuất hiện hộp hội thoại Chon file de luu với đường dẫn mặc định là D:\
Baigiang. Gõ tên tệp cần lưu dữ liệu vào ô FilName, ví dụ: Day_mua_thu_toi.doc và chọn Save. Kết
quả trong thư mục D:\Baigiang xuất hiện tệp Day_mua_thu_toi.doc chứa nội dung của hộp Textbox.

Vào Microsoft Visual Studio 2010 tạo dự án mới đặt tên là SaveDialog lưu vào thư mục D:\
Baigiang\C#HVNH\Baitap và thiết lập thuộc tính của các điều khiển như sau:

Điều khiển Name Text


Form1 frmSave Luu thong tin vao File
TextBox (MultiLine = True) txtSave
Button1 btnSave Save

Viết Code: mở cửa sổ soạn thảo Code khai báo không gian lớp IO using System.IO; và viết
đoạn mã lệnh như sau:

private void btnSave_Click(object sender, EventArgs e)


{
SaveFileDialog dlgSave = new SaveFileDialog();
dlgSave.Filter = "Text file(*.txt)|*.txt |Word
Document(*.doc) |*.docx|
All files(*.*)|*.*";
dlgSave.InitialDirectory = "D:\\Baigiang";
dlgSave.FilterIndex = 2;
dlgSave.Title = "Chon file de luu";
dlgSave.AddExtension = true;
dlgSave.DefaultExt = ".doc";
if (dlgSave.ShowDialog() == DialogResult.OK)
{
StreamWriter File;
File = new StreamWriter(dlgSave.FileName);
Bài giảng Cơ sở lập trình 2 105
try
{
File.Write(txtSave.Text);
}
catch(System.Exception)
{
MessageBox.Show("Lỗi ghi file");
}
File.Close();
}
}

3. Hộp thoại Color

Hộp thoại Color có tác dụng hiển thị bảng màu hiện hành cho phép người sử dụng chọn một màu bất
kỳ để tô màu chữ, màu nền…

Các thuộc tính của hộp thoại Color:

Thuộc tính Chức năng


Color Trả về màu được chọn trong hộp thoại Color.
FullOpen Hiển thị toàn bộ hộp thoại Color.
SolidColorOnly Không hiển thị phần Define Custom Colors.

Bài tập 21.

Viết chương trình cho phép lựa chọn màu nền cho form theo giao diện và yêu cầu sau:

Hình 42. Giao diện bài tập 22

Kích chọn nút lệnh Màu nền, xuất hiện hộp thoại Color:

Bài giảng Cơ sở lập trình 2 106


Chọn một màu bất kỳ rồi bấm OK, khi đó màu được chọn sẽ được gán làm màu nền cho form.
Vào Microsoft Visual Studio 2010 tạo dự án mới có tên là ColorDialog lưu vào thư mục D:\
Baigiang\C#HVNH\Baitap và thiết lập thuộc tính của các điều khiển như sau:

Điều khiển Name Text


Form1 frmColor Hop thoai mau
Button1 btnColor Màu nền

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void btnColor_Click(object sender, EventArgs e)


{
ColorDialog dlgColor = new ColorDialog();
dlgColor.FullOpen = true;
if (dlgColor.ShowDialog() == DialogResult.OK)
this.BackColor = dlgColor.Color;
}

4. Hộp thoại Font

Có chức năng hiển thị hộp hội thoại Font cho phép người sử dụng chọn font chữ, kiểu chữ, cỡ chữ…

Các thuộc tính quan trọng của hộp thoại Font:

Thuộc tính Chức năng

Bài giảng Cơ sở lập trình 2 107


Font Trả về kiểu Font chữ được chọn trong hộp thoại Font.
ShowColor = True: cho phép hiển thị hộp thoại Color.
Color Trả về màu được chọn trong hộp thoại Font.

Bài tập 22.

Viết chương trình cho phép lựa chọn các kiểu font chữ khác nhau cho hộp Textbox theo giao diện và
yêu cầu như sau:

Hình 43. Giao diện bài tập 22

Kích chọn nút lệnh Chọn Font, xuất hiện hộp thoại Font:

Chọn giá trị cho các thuộc tính rồi bấm OK, kết quả sẽ được hiển thị trong hộp Textbox.

Vào Microsoft Visual Studio 2010 tạo dự án mới đặt tên là FontDialog lưu vào thư mục D:\
Baigiang\C#HVNH\Baitap và thiết lập thuộc tính của các điều khiển như sau:

Bài giảng Cơ sở lập trình 2 108


Điều khiển Name Text
Form1 frmFont Hop thoai chon Font
TextBox1 txtFont Hà Nội
Button1 btnFont Chọn Font

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void btnSave_Click(object sender, EventArgs e)


{
FontDialog dlgFont = new FontDialog();
dlgFont.ShowColor = true;
if (dlgFont.ShowDialog() == DialogResult.OK)
{
txtFont.Font = dlgFont.Font;
txtFont.ForeColor = dlgFont.Color;
}
}

Bài tập 23.

Viết chương trình cho phép đọc nội dung một tệp .rtf trong máy lưu vào hộp RichTextBox theo giao
diện và yêu cầu sau:

Hình 44. Giao diện bài tập 24

Bài giảng Cơ sở lập trình 2 109


Kích chọn nút Open xuất hiện hộp thoại OpenFile, chọn tệp Main dans la main.rtf ở thư mục D:\
Baigiang\C#HVNH\Baitap\Music\Nhac_Loi lưu vào hộp RichTextBox.
Kích chọn nút Font xuất hiện hộp thoại Font, cho phép chọn mầu chữ và kiểu chữ cho hộp
RichTextbox.

Kích chọn nút Save xuất hiện hộp thoại SaveFile, lưu nội dung hộp RichTextBox vào tệp Main dans
la main.rtf

CHƯƠNG 6.
MENU VÀ ĐỒ ÁN NHIỀU BIỂU MẪU

1. Menu - MenuStrip

Điều khiển MenuStrip giúp người lập trình có thể thiết kế thanh menu trên Form.

Khi đưa điều khiển MenuStrip vào Form, một thanh menu ngang sẽ xuất hiện trên dòng đầu tiên của
Form với các ô chứa dòng chữ Type Here cho phép tạo các mục menu mới.

Bài giảng Cơ sở lập trình 2 110


Hình 45. Giao diện điều khiển MenuStrip

1.1. Thuộc tính

Name Mọi mục menu đều phải có tên, menu có tiếp đầu ngữ là mnu
Enabled = False: mục menu sẽ bị xám, ta không thể chọn mục menu đó.
Image Thiết lập hình ảnh biểu tượng cho mỗi mục menu.
ShortcutKeys Cho phép tạo phím tắt để mở các mục menu.

Text Tạo tiêu đề của các mục menu. Nếu đặt ký tự & trước một chữ cái trong
thuộc tính Text thì khi chạy chương trình người dùng có thể bấm tổ hợp
phím Alt + Chữ cái đó để kích hoạt menu. Ví dụ : &File sẽ cho phép bấm
Alt+F để kích hoạt menu File.
Nếu Text được xác lập là một dấu trừ (-) C# sẽ hiển thị một đường thẳng
ngăn cách giữa các khoản mục menu.
Visible = Flase: các mục menu sẽ không được hiển thị.
ToolTipText Tạo dòng mách nước cho các mục menu.

1.2. Sự kiện

Click Được kích hoạt khi người dùng kích chuột để chọn một mục menu.

Chú ý:

Bài giảng Cơ sở lập trình 2 111


 Chèn mục menu: để chèn thêm một mục menu vào trong danh sách các mục menu đã có, ta
kích chuột phải tại mục menu, chọn Insert/MenuItem. Kết quả một mục menu mới được
chèn vào trên mục menu đang được chọn.

 Xóa mục menu: kích chuột phải tại mục menu muốn xóa, chọn Delete.

Bài tập 24.

Tạo một menu với giao diện như sau:

Hình 46. Giao diện bài tập 25

Khi người dùng kích chuột tại mục menu nào thì xuất hiện hộp hội thoại thông báo tên mục menu
đó.

Vào Microsoft Visual Studio 2010 tạo dự án mới đặt tên là Menu và thiết lập thuộc tính của các
điều khiển như sau:

Điều khiển Name Text Image ShortcutKeys ToolTipText


Form1 frmMenu Thiet ke menu
MenuStrip1
mnuFile &File
mnuNew &New New.ico Ctrl + N Mở mới
mnuOpen &Open Open.ico Ctrl + O Mở tệp đã có
mnuSave &Save Save.ico Ctrl + S Lưu tệp
mnu1 -
mnuExit E&xit

Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh như sau:

private void mnuNew_Click(object sender, EventArgs e)


Bài giảng Cơ sở lập trình 2 112
{
MessageBox.Show("Bạn đã chọn mục menu New", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}

private void mnuOpen_Click(object sender, EventArgs e)


{
MessageBox.Show("Bạn đã chọn mục menu Open", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
………// Các mục menu khác làm tương tự

2. Popup menu - ContextMenuStrip

Điều khiển ContextMenuStrip cho phép tạo menu ngữ cảnh, menu này chỉ xuất
hiện khi người dùng kích chuột phải tại điều khiển gắn menu. Ta gắn menu ngữ cảnh cho một điều
khiển thông qua thuộc tính Context MenuStrip của điều khiển đó.

Điều khiển ContextMenuStrip có tiếp đầu ngữ là cmnu và có các thuộc tính và phương thức tương
tự như điều khiển MenuStrip.

Bài tập 25.

Viết chương trình tạo menu Popup có giao diện và các chức năng như sau:

 Người dùng kích chuột phải tại vị trí bất kỳ trên Form, xuất hiện menu gồm 2 mục lựa chọn:
Open và Save. Kích chọn mục Open sẽ xuất hiện hộp thoại Open cho phép chọn một tệp văn bản
bất kỳ có đuôi .rtf và hiển thị nội dung của tệp văn bản vào hộp RichTextBox Văn bản 1.

 Bôi đen các dòng văn bản trong hộp Văn bản 1 và kích chuột phải tại vị trí bất kỳ trong hộp Văn
bản 1, xuất hiện menu gồm 4 mục lựa chọn: Copy, Cut, Paste và Delete. Kích chọn mục Copy để
lưu các dòng văn bản được bôi đen vào bộ nhớ đệm ClipBoard.

 Kích chuột phải tại vị trí bất kỳ trong hộp Văn bản 2 chọn Paste để gán nội dung dòng văn bản
trong ClipBoard vào hộp Văn bản 2.

Bài giảng Cơ sở lập trình 2 113


Hình 47. Giao diện bài tập 26

Vào Microsoft Visual Studio 2010 tạo dự án mới có tên là MenuPopup và thiết lập giá trị cho các
thuộc tính của các điều khiển như sau:

Điều khiển Name Text Image Context Shortcut


MenuStrip Keys
Form1 frmMenuPopup Thiet ke cmnuFile
menu popup
ContextMenu cmnuFile
Strip1
cmnuOpen Open Open.ico Ctrl + O
cmnuSave Save Save.ico Ctrl + S
ContextMenu cmnuEdit
Strip2 cmnuCopy Copy Ctrl + C
cmnuCut Cut Ctrl + X
cmnuPaste Paste Ctrl + V
cmnuDelete Delete Delete.ico
Label1 Văn bản 1
Label2 Văn bản 2
RichTextBox1 rtbVanban1 cmnuEdit
RichTextBox2 rtbVanban2 cmnuEdit
Viết Code: mở cửa sổ soạn thảo Code và viết các đoạn mã lệnh cho 2 mục menu cmnuCopy và
cmnuPaste như sau:

Bài giảng Cơ sở lập trình 2 114


private void cmnuCopy_Click(object sender, EventArgs e)
{
Clipboard.SetText(rtbVanban1.SelectedText);
}

private void cmunPaste_Click(object sender, EventArgs e)


{
//rtbVanban2.Text = Clipboard.GetText(); // cách 1
//rtbVanban2.Text =
rtbVanban2.Text.Insert(rtbVanban2.SelectionStart,
Clipboard.GetText()); // Cách 2
rtbVanban2.SelectedText = Clipboard.GetText(); // cách 3
}

private void mnuCut_Click(object sender, EventArgs e)


{
Clipboard.SetText(rtbVanban1.SelectedText);
rtbVanban1.SelectedText = String.Empty;
}

// Các mục menu khác sinh viên tự làm

3. Đồ án nhiều biểu mẫu

Khi ứng dụng trở lên phức tạp, chương trình không thể chỉ chứa trong một biểu mẫu mà phải sử
dụng nhiều biểu mẫu để bổ sung tính linh hoạt và năng lực cho ứng dụng.

3.1. Bổ sung biểu mẫu

Để bổ sung thêm các biểu mẫu - Form cho ứng dụng đang thiết kế, ta có thể thực hiện một trong các
cách sau :

 Chọn menu Project/Add Windows Form…

 Hoặc chọn menu Project/Add New Item…

 Hoặc bấm phím tắt Ctrl+Shift+A

Kết quả xuất hiện cửa sổ Add New Item. C# cung cấp vài biểu mẫu được xây dựng sẵn để có thể bổ
sung vào dự án, ví dụ: biểu mẫu cơ bản ‘Windows Form’, hoặc ‘About Box’ - dùng để đặt logo của
công ty hoặc ký hiệu bản quyền...

Chọn loại biểu mẫu cần bổ sung ví dụ Windows Form, đặt tên cho form tại ô Name rồi chọn nút
Add, khi đó một biểu mẫu mới sẽ được chèn vào ứng dụng.

Bài giảng Cơ sở lập trình 2 115


Hình 48. Cửa sổ Add New Item

Ngoài ra C# còn cho phép bổ sung các form đã được xây dựng trong các dự án khác bằng cách chọn
menu Project/ Add Existing Item… hoặc bấm phím tắt Shift+Alt+A rồi chọn Form cần bổ sung. Việc
chèn Form đã có sẵn tạo điều kiện cho việc phân nhỏ ứng dụng cho nhiều người, mỗi người làm một
phần sau đó ghép lại với nhau tạo thành ứng dụng hoàn chỉnh.

Bài tập 26.

Vào Microsoft Visual Studio 2010 tạo dự án mới có tên là English lưu vào thư mục D:\Baigiang\
C#HVNH\Baitap.

 Đổi tên cho Form1 thành frmMain và tiêu đề là Bai tap tieng Anh.

 Bổ sung thêm 2 Windows Form mới có tên là frmDientu1 và frmBiendoi1 với tiêu đề lần
lượt là Bai tap Dien tu 1 và Bai tap Bien doi cau.

Lúc này dự án có 03 Form là: frmMain, frmDientu1 và frmBiendoi1.

3.2. Biểu mẫu khởi động

Khi chạy một ứng dụng, biểu mẫu được thực hiện đầu tiên gọi là biểu mẫu khởi động - Startup.

Bài giảng Cơ sở lập trình 2 116


Biểu mẫu Startup mặc định là biểu mẫu đầu tiên được xây dựng trong ứng dụng khi thiết kế giao
diện, ví dụ biểu mẫu frmMain trong ứng dụng English.

Ta có thể thay đổi mặc định này để có thể chọn một biểu mẫu bất kỳ làm biểu mẫu khởi động khi
chạy chương trình. Ví dụ muốn form frmDientu1 được thực hiện đầu tiên, ta thực hiện như sau:

 Kích chuột phải tại tệp Program.cs trong cửa sổ Solution Explorer, chọn Open hoặc View
Code.

 Trong hàm Main của cửa sổ code sửa dòng Application.Run(new frmMain()); thành
Application.Run(new frmDientu1());

3.3. Gọi biểu mẫu

Để gọi một biểu mẫu ta phải khai báo một biến có kiểu của biểu mẫu cần gọi và thực hiện gọi thông
qua 2 phương thức tương ứng với 2 cách sau :

Cách 1: Dùng phương thức Show()

Ví dụ: frmDientu1 frm = new frmDientu1();


frm.Show();

Phương thức này tải biểu mẫu vào bộ nhớ sau đó đưa biểu mẫu lên phía trên các biểu mẫu khác,
đồng thời vẫn cho phép người sử dụng có thể tương tác được với các biểu mẫu nằm phía dưới.

Cách 2: Dùng phương thức ShowDialog()

Ví dụ: frmDientu1 frm = new frmDientu1();


frm.ShowDialog();

Tương tự như cách 1 nhưng người sử dụng chỉ có thể tương tác được với biểu mẫu hiện hành mà
không thể tương tác với các biểu mẫu nằm phía dưới nó.

3.4. Đóng biểu mẫu

Để đóng một biểu mẫu ta có thể thực hiện theo 2 cách sau:

 Cách 1: cú pháp this.Hide();

 Cách 2: cú pháp this.Close();

3.5. Xoá biểu mẫu

Trong cửa sổ Solution Explorer, kích chuột phải tại Form cần xóa, chọn Delete. Kết quả Form được
chọn sẽ bị xóa ra khỏi dự án.

Bài tập 27.

Bài giảng Cơ sở lập trình 2 117


Tiếp theo bài tập 27, tạo MenuStrip cho Form frmMain theo giao diện sau:

Hình 49. Giao diện bài tập 28

 Đặt tên cho mục menu Dien tu là mnuDientu, tiêu đề là &Dien tu

 Đặt tên cho menu con 1 của Dien tu là mnuDientu1, tiêu đề là Bai dien tu &1

 Thực hiện tương tự cho các mục còn lại…

Tiếp theo bài tập 28, tạo form frmDientu1 với giao diện và các chức năng như sau:

Hình 50. Giao diện bài tập 29

Bài giảng Cơ sở lập trình 2 118


 Khi gọi Form frmDientu1 xuất hiện nội dung bài tập cần điền từ trong hộp Textbox.

 Người sử dụng viết đáp án cho các câu vào các ô Textbox từ 1 đến 10.

 Khi chọn nút OK chương trình kiểm tra kết quả, câu nào đúng thì đổi mầu nền ở Textbox
tương ứng với câu trả lời sang mầu xanh, câu nào sai thì đổi Textbox có nền mầu hồng. Và
hiển thị điểm đạt được cho người dùng (mỗi câu trả lời đúng được 1 điểm).

 Khi chọn nút Dapan thì form sẽ hiển thị đáp án như giao diện sau:

 Bấm nút Làm lại, xuất hiện nội dung đề bài và xoá rỗng các đáp án cũ để người dùng có thể
trả lời lại các câu hỏi.

 Bấm nút Exit để đóng form frm Dientu1 trở về form chính frmMain.

Bài tập 28.

Tiếp theo bài tập 29, tạo form frmBiendoi1 có giao diện và các chức năng như sau:

 Khi gọi Form frmBiendoi1 xuất hiện nội dung các câu cần viết lại trong các nhãn Label với
thứ tự từ 1 đến 10.

 Người dùng viết câu mới có ý nghĩa tương tự với câu đã cho trong các nhãn Label vào các
hộp Textbox tương ứng ở phía dưới bắt đầu bởi các từ hướng dẫn cho trước.

Bài giảng Cơ sở lập trình 2 119


Hình 51. Giao diện bài tập 30

 Các nút OK, Đáp án, Làm lại và Exit có chức năng tương tự như trong form frmDientu1.

 Khi người dùng bấm nút Help, xuất hiện hộp thông báo chứa các gợi ý cho các câu trả lời
như sau:

Bài giảng Cơ sở lập trình 2 120


Bài giảng Cơ sở lập trình 2 121
CHƯƠNG 7.
LẬP TRÌNH CƠ SỞ DỮ LIỆU

Lập trình cơ sở dữ liệu là một trong những thế mạnh của C# cho phép dễ dàng tạo ra những phần
mềm quản lý chuyên nghiệp, được kết nối tới cơ sở dữ liệu của các hệ quản trị cơ sở dữ liệu cho
phép Thêm, Sửa, Xoá, Tìm kiếm và kết xuất dữ liệu với độ chính xác cao, chức năng phong phú và
giao diện thân thiện.

Trong phần này ta sẽ viết chương trình minh họa việc lập trình cơ sở dữ liệu trong C#. Các bước
thực hiện như sau:

1. Giới thiệu bài toán

Viết chương trình quản lý cửa hàng Bán hàng lưu niệm, cho phép cập nhập các mặt hàng, viết hoá
đơn nhập xuất, tìm kiếm các thông tin, báo cáo tình hình doanh thu,…

2. Tạo cơ sở dữ liệu

Vào Microsoft Visual Studio 2010 tạo dự án mới có tên là Quanlybanhang và lưu vào thư mục D:\
TenSV. Trong dự án ta tạo một số thư mục để lưu các nhóm đối tượng khác nhau.

Trước hết ta tạo thư mục Database để lưu CSDL của dự án. Trong cửa sổ Solution Explorer kích
chuột phải tại tên dự án, chọn Add, chọn New Folder.

Hình 52. Giao diện tạo thư mục mới

Tại cửa sổ Solution Explorer xuất hiện thư mục New Folder1, ta đổi tên thành Database.
Bài giảng Cơ sở lập trình 2 122
Kích chuột phải tại thư mục Database, chọn Add, chọn New Item… hoặc kích chuột chọn thư mục
Database rồi vào menu Project chọn Add New Item…

Xuất hiện cửa sổ Add New Item:

Hình 53. Giao diện tạo Database

Chọn Service-based Database (chọn SQL Database nếu là bản Visual Studio Net 2005), tại ô Name
đặt tên cho cơ sở dữ liệu là Dulieu.mdf rồi bấm nút Add.

Bài giảng Cơ sở lập trình 2 123


Kết quả xuất hiện hộp hội thoại Data Source Configuration Wizrad:

Hình 54. Data Source Configuration Wizrad bản 2010

Chọn Cancel để tạo một Database mới.

(Đối với bản 2005 chọn 4 kiểu thao tác CSDL như hình sau rồi chọn Finish

Hình 55. Data Source Configuration Wizrad bản 2005)

Kết quả trong thư mục Database xuất hiện đối tượng Dulieu.mdf, kích đúp vào đối tượng này xuất
hiện cửa sổ Server Explorer cho phép tạo cơ sở dữ liệu cho dự án.

Bài giảng Cơ sở lập trình 2 124


Hình 56. Giao diện cửa sổ Server Explorer

2.1. Tạo bảng tblChatlieu

Kích chuột phải tại Tables, chọn Add New Table xuất hiện một cửa sổ cho phép tạo một bảng mới.
Tạo bảng chất liệu gồm các trường như sau:

Hình 57. Tạo bảng tblChatlieu

Để tạo khóa cho bảng ta kích chuột phải tại dòng Machatlieu chọn Set Primary Key.

Bấm Ctrl+S, trong hộp thoại Choose Name, đặt tên cho bảng là tblChatlieu rồi bấm OK.

2.2. Tạo bảng tblHang

Bài giảng Cơ sở lập trình 2 125


2.3. Tạo bảng tblNhanvien

2.4. Tạo bảng tblKhach

2.5. Tạo bảng tblHDBan

2.6. Tạo bảng tblChitietHDBan

Bài giảng Cơ sở lập trình 2 126


2.7. Tạo quan hệ Relationship

Kích chuột phải tại Database Diagrams chọn Add New Diagram và tạo Relationship như hình dưới
đây:

Hình 58. Quan hệ Relationship

2.8. Tạo kết nối cơ sở dữ liệu

Để cập nhật dữ liệu vào các bảng trong CSDL Dulieu.mdf ta thực hiện theo các bước sau:
Bài giảng Cơ sở lập trình 2 127
Bước 1: Xoá bản sao cơ sở dữ liệu Dulieu.mdf trong cửa sổ Solution Explorer. Kích chuột phải tại
thư mục Database chọn Exclude From Project (chú ý phải lưu đồ án trước khi thực
hiện bước này)

Hình 59. Xoá bản sao cơ sở dữ liệu

Bước 2: Kết nối tới cơ sở dữ liệu Dulieu.mdf trong thư mục D:\TenSV\Quanlybanhang\
Quanlybanhang\Database.

Trong cửa sổ Server Explorer kích chuột phải tại Data Connections chọn Add Connection… xuất
hiện hộp thoại Choose Data Source

Trong hộp thoại Choose Data Source chọn Microsoft SQL Server Database File, chọn Continue.
Xuất hiện hộp thoại Add Connection:

Bài giảng Cơ sở lập trình 2 128


Hình 60. Kết nối cơ sở dữ liệu Dulieu.mdf

Kích chọn nút Browse, tìm và kích đúp tại tệp Dulieu.mdf (tại D:\TenSV\Quanlybanhang\
Quanlybanhang\Database). Kích chọn nút Test Connection, nếu thành công sẽ xuất hiện hộp thoại
sau:

Kích chọn OK/OK. Kết quả tệp dữ liệu Dulieu.mdf đã được kết nối.

3. Tạo thư mục chứa ảnh

Bài giảng Cơ sở lập trình 2 129


Chương trình phải quản lý rất nhiều tệp ảnh như ảnh nền của Form, ảnh minh họa của các mặt
hàng… do đó ta tạo một thư mục Images để chứa danh sách các tệp ảnh này. Trong cửa sổ Solution
Explorer kích chuột phải tại tên dự án Quanlybanhang, chọn Add, chọn New Folder, đổi tên thư
mục mới xuất hiện thành Images.

Kích chuột phải tại thư mục Images, chọn Add, chọn Existing Item… xuất hiện cửa sổ Add Existing
Item, tìm đường dẫn đến các tệp ảnh của chương trình và chọn nút Add để lưu các tệp ảnh đó vào
thư mục Images.

4. Xây dựng Form chính cho chương trình

4.1. Tạo giao diện Form chính

Sửa lại một số thuộc tính của Form1 như sau:

Name frmMain
Text Quan ly ban hang
WindowState Maximized
Icon /Images/Users.ico
BackgroundImage /Images/bg0_4.jpg

Tạo menu cho chương trình gồm các mục menu với thuộc tính Name và Text như sau:

Danh mục mnuDanhmuc


Chất liệu mnuChatlieu
Nhân viên mnuNhanvien
Khách hàng mnuKhachhang
Hàng hóa mnuHanghoa
Hóa đơn mnuHoadon
Hóa đơn bán mnuHoadonban
Tìm kiếm mnuTimkiem
Hóa đơn mnuFindHoadon

Hàng mnuFindHang
Khách hàng mnuFindKhachhang
Báo cáo mnuBaocao
Hàng tồn mnuBCHangton
Doanh thu mnuBCDoanhthu
Trợ giúp mnuHelp
Thoát mnuThoat

Thêm 2 nhãn Label với Text là: ‘Chương trình quản lý’ và ‘Bán hàng lưu niệm’

Bài giảng Cơ sở lập trình 2 130


Hình 61. Giao diện form chính

4.2. Viết mã lệnh Form chính

Form frmMain có nhiệm vụ kết nối tới cơ sở dữ liệu khi bắt đầu thực hiện dự án, đóng kết nối tới cơ
sở dữ liệu khi đóng dự án và mở các form tương ứng với các mục menu.

public partial class frmMain : Form


{
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
Class.Functions.Connect();
}
private void mnuThoat_Click(object sender, EventArgs e)
{
Class.Functions.Disconnect();
Application.Exit();
}
private void mnuChatlieu_Click(object sender, EventArgs e)
{
Forms.frmDMChatlieu f = new Forms.frmDMChatlieu();
Bài giảng Cơ sở lập trình 2 131
f.StartPosition = FormStartPosition.CenterScreen;
f.Show();
}
}

Trong đó Connect và Disconnect là hai hàm toàn cục được viết trong class Funtions, có tác dụng tạo
kết nối và đóng kết nối tới CSDL.

Các hàm viết trong class sẽ được truy xuất bởi tất cả các đối tượng có trong dự án.

4.3. Tạo lớp – Class Functions

Trong cửa sổ Solution Explorer tạo một thư mục mới đặt tên là Class, kích chuột phải tại Class chọn
Add/ New Item… chọn Class trong hộp thoại Add New Item và đặt tên cho class là Functions.cs tại ô
Name.

Mã lệnh của lớp Functions được viết như sau:

Để sử dụng thư viện các đối tượng của SQL Server và sử dụng đối tượng Dataset ta phải khai báo 2
Namespace Data và Data.SqlClient.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms; // Sử dụng hàm MessageBox

namespace Quanlybanhang.Class
{
class Functions
{
public static SqlConnection Conn; //Khai báo đối tượng kết nối
public static string connString; //Khai báo biến chứa chuỗi kết nối

public static void Connect()


{
//Thiết lập giá trị cho chuỗi kết nối
connString = "Data Source=.\\SQLEXPRESS;
AttachDbFilename= D:\\Baigiang\\
C#HVNH\\Baitap\\Quanlybanhang\\Quanlybanhang\\
Database\\Dulieu.mdf;
Integrated Security=True;Connect Timeout=30;User
Instance=True";
Conn = new SqlConnection(); //Cấp phát
đối tượng
Bài giảng Cơ sở lập trình 2 132
Conn.ConnectionString = connString; //Kết nối
Conn.Open(); //Mở kết nối
}

public static void Disconnect()


{
if (Conn.State == ConnectionState.Open)
{
Conn.Close(); //Đóng kết nối
Conn.Dispose(); //Giải phóng tài nguyên
Conn = null;
}
}
}
}
Để xác định giá trị cho chuỗi kết nối, trong cửa sổ Server Explorer kích chọn tệp dữ liệu Dulieu.mdf,
chuỗi kết nối là giá trị của thuộc tính Connection String trong cửa sổ Properties.

5. Xây dựng Form cập nhật danh mục Chất liệu

Trong cửa sổ Solution Explorer tạo một thư mục mới đặt tên là Forms, kích chuột phải tại Forms,
chọn Add, chọn New Item… Trong cửa sổ Add New Item chọn WindowForms và đặt tên cho Form
tại ô Name là frmDMChatlieu rồi bấm Add.

Form frmDMChatlieu cho phép thêm, xem, xoá, sửa danh sách các loại chất liệu trong bảng
tblChatlieu.

Bài giảng Cơ sở lập trình 2 133


Hình 62. Giao diện form Chất liệu

5.1. Tạo giao diện Form frmDMChatlieu

Điều khiển Name Text


Form frmDMChatlieu DANH MUC CHAT LIEU
TextBox txtMachatlieu
txtTenchatlieu
Button btnThem Thêm
btnXoa Xoá
btnSua Sửa
btnLuu Lưu
btnBoqua Bỏ qua
btnDong Đóng
DataGridView DataGridView

5.2. Viết mã lệnh Form frmDMChatlieu

5.2.1. Khai báo các lớp tham chiếu


using System.Data;
Bài giảng Cơ sở lập trình 2 134
using System.Data.SqlClient;

// Khai báo biến toàn cục


DataTable tblCL;

5.2.2. Viết thủ tục Form_Load của dự án


private void frmDMChatlieu_Load(object sender, EventArgs e)
{
txtMachatlieu.Enabled = false;
btnLuu.Enabled = false;
btnBoqua.Enabled = false;
Load_DataGridView();
}

Với Load_DataGridView là thủ tục cục bộ được viết trong phần code của form frmDM Chatlieu có
tác dụng lấy dữ liệu từ bảng tblChatlieu đổ vào lưới DataGrid View.

5.2.3. Viết thủ tục Load_DataGridView


private void Load_DataGridView()
{
string sql;
sql = "SELECT Machatlieu, Tenchatlieu FROM tblChatlieu";
tblCL = Class.Functions.GetDataToTable(sql);
DataGridView.DataSource = tblCL;

//do dl tu bang vao datagridview

DataGridView.Columns[0].HeaderText = "Mã chất liệu";


DataGridView.Columns[1].HeaderText = "Tên chất liệu";
DataGridView.Columns[0].Width = 100;
DataGridView.Columns[1].Width = 300;
// Không cho phép thêm mới dữ liệu trực tiếp trên lưới
DataGridView.AllowUserToAddRows = false ;
// Không cho phép sửa dữ liệu trực tiếp trên lưới
DataGridView.EditMode =
DataGridViewEditMode.EditProgrammatically;
}

Với GetDataToTable là hàm toàn cục được viết trong lớp Functions có tác dụng thực hiện câu lệnh
SQL truy vấn dữ liệu từ CSDL đổ vào đối tượng bảng trong C#.

5.2.4. Viết hàm GetDataToTable

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

Bài giảng Cơ sở lập trình 2 135


public static DataTable GetDataToTable(string sql)
{
SqlDataAdapter Mydata = new SqlDataAdapter(); // Khai báo
// Tạo đối tượng Command thực hiện câu lệnh SELECT
Mydata.SelectCommand = new SqlCommand();
Mydata.SelectCommand.Connection = Functions.Conn; // Kết
nối CSDL
Mydata.SelectCommand.CommandText = sql; // Gán câu lệnh
SELECT
DataTable table = new DataTable(); // Khai báo DataTable
nhận dữ liệu trả về
Mydata.Fill(table); //Thực hiện câu lệnh SELECT và đổ dữ
liệu vào bảng table
return table;
}

Hoặc có thể thực hiện ngắn gọn bằng cách gán tham số khi khai báo đối tượng như sau:

public static DataTable GetDataToTable(string sql)


{
SqlDataAdapter Mydata = new SqlDataAdapter(sql,
Functions.Conn);
DataTable table = new DataTable();
Mydata.Fill(table);
return table;
}

5.2.5. Tìm hiểu đối tượng SqlDataAdapter

SqlDataAdapter là đối tượng dùng để điều phối dữ liệu, tức là nó không lưu trữ dữ liệu mà chỉ phát
đi các lệnh SQL và nhận dữ liệu trả về của CSDL sau đó chuyển cho đối tượng khác (thường là
DataTable).

Đối tượng SqlDataAdapter nằm trong thư viện System.Data.SqlClient.

SqlDataAdapter có thể thực hiện cùng một lúc các lệnh SQL gồm: SELECT, INSERT, UPDATE,
DELETE thông qua các thành phần cơ bản sau:

 SelectCommand: truy vấn dữ liệu, tương ứng với lệnh SELECT trong SQL.

 InsertCommand: chèn dữ liệu mới, tương ứng với lệnh INSERT.

 UpdateCommand: cập nhật dữ liệu, tương ứng với lệnh UPDATE.

 DeleteCommand: xóa dữ liệu, tương ứng với lệnh DELETE.

SqlDataAdapter có 2 phương thức cơ bản Fill() và Update():

Bài giảng Cơ sở lập trình 2 136


 Fill: thực thi câu lệnh SelectCommand và đổ dữ liệu vào đối tượng DataTable.

 Update: thực thi các câu lệnh InsertCommand, UpdateCommand, DeleteCommand.

5.2.6. Viết thủ tục DataGridView_Click

Thủ tục này có tác dụng lấy nội dung dòng dữ liệu người dùng kích chọn trong lưới DataGridView
và hiển thị lên các điều khiển trên Form.

private void DataGridView_Click(object sender, EventArgs e)


{
if (btnThem.Enabled == false)
{
MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtMachatlieu.Focus();
return;
}
if (tblCL.Rows.Count == 0 )
{
MessageBox.Show("Không có dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
txtMachatlieu.Text =
DataGridView.CurrentRow.Cells["Machatlieu"].Value.ToString();
txtTenchatlieu.Text =
DataGridView.CurrentRow.Cells["Tenchatlieu"].Value.ToString();
btnSua.Enabled = true;
btnXoa.Enabled = true;
btnBoqua.Enabled = true;
}

5.2.7. Viết thủ tục btnThem_Click


private void btnThem_Click(object sender, EventArgs e)
{
btnSua.Enabled = false;
btnXoa.Enabled = false;
btnBoqua.Enabled = true;
btnLuu.Enabled = true;
btnThem.Enabled = false;
ResetValues();
txtMachatlieu.Enabled = true;
txtMachatlieu.Focus();
Bài giảng Cơ sở lập trình 2 137
}

Với ResetValues là thủ tục cục bộ được viết trong phần code của form frmDMChatlieu có tác dụng
xóa hết dữ liệu trong các điều khiển trên Form.

5.2.8. Viết thủ tục ResetValues


private void ResetValues()
{
txtMachatlieu.Text = "";
txtTenchatlieu.Text = "";
}

5.2.9. Viết thủ tục btnLuu_Click

Thủ tục này có tác dụng kiểm tra thông tin người dùng nhập vào các điều khiển trên Form trong
trường hợp thêm mới và lưu các thông tin đó vào CSDL.

private void btnLuu_Click(object sender, EventArgs e)


{
string sql;
if (txtMachatlieu.Text==””)
{
MessageBox.Show("Bạn phải nhập mã chất liệu", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtMachatlieu.Focus();
return;
}
if (txtTenchatlieu.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập tên chất liệu", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtTenchatlieu.Focus();
return ;
}
sql = "SELECT MaChatlieu FROM tblChatlieu WHERE
MaChatlieu=N'" +
txtMachatlieu.Text.Trim() + "'";
if (Class.Functions.CheckKey(sql))
{
MessageBox.Show("Mã chất liệu này đã có, bạn phải nhập mã
khác", "Thông

Bài giảng Cơ sở lập trình 2 138


báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtMachatlieu.Focus();
txtMachatlieu.Text = "";
return;
}
sql = "INSERT INTO tblChatlieu(Machatlieu,Tenchatlieu)
VALUES(N'" +
txtMachatlieu.Text + "',N'" + txtTenchatlieu.Text + "')";
Class.Functions.RunSql(sql);
Load_DataGridView();
ResetValues();
btnXoa.Enabled = true;
btnThem.Enabled = true;
btnSua.Enabled = true;
btnBoqua.Enabled = false;
btnLuu.Enabled = false;
txtMachatlieu.Enabled = false;
}

Với CheckKey và RunSql là các hàm và thủ tục toàn cục được viết trong lớp Functions.

CheckKey có tác dụng kiểm tra khóa trùng, RunSql có tác dụng thực thi các câu lệnh SQL.

5.2.10. Viết hàm CheckKey

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

public static bool CheckKey(string sql)


{
SqlDataAdapter Mydata = new SqlDataAdapter(sql,
Functions.Conn);
DataTable table = new DataTable();
Mydata.Fill(table);
if (table.Rows.Count > 0)
return true;
else
return false;
}

5.2.11. Viết thủ tục RunSql

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

public static void RunSql(string sql)

Bài giảng Cơ sở lập trình 2 139


{
SqlCommand cmd; // Khai báo đối tượng
SqlCommand
cmd = new SqlCommand(); // Khởi tạo đối tượng
cmd.Connection = Functions.Conn; // Gán kết nối
cmd.CommandText = sql; // Gán câu lệnh SQL
try
{
cmd.ExecuteNonQuery(); // Thực hiện câu lệnh SQL
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
cmd.Dispose();
cmd = null;
}

Chú ý: Đối tượng SqlCommand có hai phương thức để thực thi câu lệnh SQL, trong đó:

 ExecuteReader: thực thi câu lệnh SQL có dữ liệu trả về, ví dụ SELECT.

 ExecuteNoneQuery: thực thi các câu lệnh SQL không yêu cầu trả về tập dữ liệu, ví dụ:
INSERT, UPDATE, DELETE.

5.2.12. Viết thủ tục btnSua_Click

Khi người dùng kích chuột vào một dòng bản ghi bất kỳ trên lưới để hiển thị dữ liệu của bản ghi đó
lên Form thì người dùng có thể chỉnh sửa các thông tin đó.

Thủ tục btnSua_Click có tác dụng lưu các thông tin người dùng đã sửa vào CSDL.

private void btnSua_Click(object sender, EventArgs e)


{
string sql;
if (tblCL.Rows.Count == 0 )
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return ;
}
if (txtMachatlieu.Text == "" )
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);

Bài giảng Cơ sở lập trình 2 140


return ;
}
if (txtTenchatlieu.Text.Trim().Length == 0 )
{
MessageBox.Show("Bạn phải nhập tên chất liệu", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtTenchatlieu.Focus();
return ;
}
sql = "UPDATE tblChatlieu SET Tenchatlieu=N'" +
txtTenchatlieu.Text.ToString() +
"' WHERE Machatlieu=N'" + txtMachatlieu.Text + "'";
Class.Functions.RunSql(sql);
Load_DataGridView();
ResetValues();
btnBoqua.Enabled = false;
}

5.2.13. Viết thủ tục btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
{
string sql;
if (tblCL.Rows.Count == 0)
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return ;
}
if (txtMachatlieu.Text == "" )
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return ;
}
if (MessageBox.Show("Bạn có muốn xóa không?", "Thông báo",
MessageBoxButtons.OKCancel,MessageBoxIcon.Question) == DialogResult.OK)
{
sql = "DELETE tblChatlieu WHERE Machatlieu=N'" +
txtMachatlieu.Text + "'";
Class.Functions.RunSqlDel(sql);
Load_DataGridView();
ResetValues();

Bài giảng Cơ sở lập trình 2 141


}
}

5.2.14. Viết thủ tục RunSqlDel

Thủ tục RunSqlDel tương tự như RunSql nhưng trong trường hợp xóa dữ liệu nếu dữ liệu đang được
dùng bởi một đối tượng khác thì không được phép xóa.

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

public static void RunSqlDel(string sql)


{
SqlCommand cmd = new SqlCommand();
cmd.Connection = Functions.Conn;
cmd.CommandText = sql;
try
{
cmd.ExecuteNonQuery();
}
catch (System.Exception)
{
MessageBox.Show("Dữ liệu đang được dùng, không thể
xóa...", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
cmd.Dispose();
cmd = null;
}

5.2.15. Viết thủ tục btnBoqua_Click

Thủ tục này là thủ tục cục bộ được gọi khi người dùng muốn hủy bỏ các chức năng Thêm mới hoặc
Sửa dữ liệu.

private void btnBoqua_Click(object sender, EventArgs e)


{
ResetValues();
btnBoqua.Enabled = false;
btnThem.Enabled = true;
btnXoa.Enabled = true;
btnSua.Enabled = true;
btnLuu.Enabled = false;
txtMachatlieu.Enabled = false;
}

5.2.16. Viết thủ tục dùng phím Enter thay cho phím Tab

Bài giảng Cơ sở lập trình 2 142


private void txtMachatlieu_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
SendKeys.Send("{TAB}");
}

Thực hiện tương tự cho txtTenchatlieu_KeyUp

5.2.17. Viết thủ tục btnDong_Click


private void btnDong_Click(object sender, EventArgs e)
{
this.Close();
}

6. Xây dựng Form cập nhật danh mục Nhân viên

Mở một Form mới đặt tên là frmDMNhanvien rồi lưu vào thư mục Forms.

Hình 63. Giao diện form Nhân viên

Bài giảng Cơ sở lập trình 2 143


Form frmDMNhanvien cho phép thêm, xem, xoá, sửa danh sách các nhân viên trong bảng
tblNhanvien.

6.1. Tạo giao diện Form frmDMNhanvien

Điều khiển Name Text


Form frmDMNhanvien DANH MUC NHAN VIEN
TextBox txtManhanvien
txtTennhanvien
txtDiachi
Button btnThem, btnXoa, btnSua, btnLuu, btnBoqua, btnDong
CheckBox chkGioitinh Nam
MaskedTextBox mskDienthoai Mask: Phone Number
mskNgaysinh Mask: Short Date
DataGridView DataGridView
6.2. Viết mã lệnh Form frmDMNhanvien

6.2.1. Khai báo các lớp tham chiểu


using System.Data;
using System.Data.SqlClient;
using Quanlybanhang.Class; // Khai báo lớp Functions

// Khai báo biến toàn cục


DataTable tblNV;

6.2.2. Viết thủ tục FormLoad


private void frmDMNhanvien_Load(object sender, EventArgs e)
{
txtManhanvien.Enabled = false;
btnLuu.Enabled = false;
btnBoqua.Enabled = false;
Load_DataGridView();
}

6.2.3. Viết thủ tục Load_DataGridView – Hiển thị dữ liệu lên lưới
private void Load_DataGridView()
{
string sql;
sql = "SELECT Manhanvien, Tennhanvien, Gioitinh, Diachi,
Dienthoai, Ngaysinh
FROM tblNhanvien";
Bài giảng Cơ sở lập trình 2 144
tblNV = Functions.GetDataToTable(sql);
DataGridView.DataSource = tblNV;
DataGridView.Columns[0].HeaderText = "Mã nhân viên";
DataGridView.Columns[1].HeaderText = "Tên nhân viên";
DataGridView.Columns[2].HeaderText = "Giới tính";
DataGridView.Columns[3].HeaderText = "Địa chỉ";
DataGridView.Columns[4].HeaderText = "Điện thoại";
DataGridView.Columns[5].HeaderText = "Ngày sinh";
DataGridView.Columns[0].Width = 100;
DataGridView.Columns[1].Width = 150;
DataGridView.Columns[2].Width = 100;
DataGridView.Columns[3].Width = 150;
DataGridView.Columns[4].Width = 100;
DataGridView.Columns[5].Width = 100;
DataGridView.AllowUserToAddRows = false;
DataGridView.EditMode =
DataGridViewEditMode.EditProgrammatically;
}

6.2.4. Viết thủ tục DataGridView_Click


private void DataGridView_Click(object sender, EventArgs e)
{
if (btnThem.Enabled == false)
{
MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtManhanvien.Focus();
return;
}
if (tblNV.Rows.Count == 0)
{
MessageBox.Show("Không có dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
txtManhanvien.Text =
DataGridView.CurrentRow.Cells["Manhanvien"].Value.ToString();
txtTennhanvien.Text =
DataGridView.CurrentRow.Cells["Tennhanvien"].Value.ToString();
if (DataGridView.CurrentRow.Cells["Gioitinh"].Value.ToString() ==
"Nam")
chkGioitinh.Checked = true;
else

Bài giảng Cơ sở lập trình 2 145


chkGioitinh.Checked = false;
txtDiachi.Text =
DataGridView.CurrentRow.Cells["Diachi"].Value.ToString();
mskDienthoai.Text =
DataGridView.CurrentRow.Cells["Dienthoai"].Value.ToString();
mskNgaysinh.Text =
DataGridView.CurrentRow.Cells["Ngaysinh"].Value.ToString ();
btnSua.Enabled = true;
btnXoa.Enabled = true;
btnBoqua.Enabled = true;
}

6.2.5. Viết thủ tục btnThem_Click


private void btnThem_Click(object sender, EventArgs e)
{
btnSua.Enabled = false;
btnXoa.Enabled = false;
btnBoqua.Enabled = true;
btnLuu.Enabled = true;
btnThem.Enabled = false;
ResetValues();
txtManhanvien.Enabled = true;
txtManhanvien.Focus();
}

6.2.6. Viết thủ tục ResetValues


private void ResetValues()
{
txtManhanvien.Text = "";
txtTennhanvien.Text = "";
chkGioitinh.Checked = false;
txtDiachi.Text = "";
mskNgaysinh.Text = "";
mskDienthoai.Text = "";
}

6.2.7. Viết thủ tục btnLuu_Click


private void btnLuu_Click(object sender, EventArgs e)
{
string sql,gt;
if (txtManhanvien.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập mã nhân viên", "Thông
báo",

Bài giảng Cơ sở lập trình 2 146


MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtManhanvien.Focus();
return;
}
if (txtTennhanvien.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập tên nhân viên", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtTennhanvien.Focus();
return ;
}
if (txtDiachi.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtDiachi.Focus();
return ;
}
if (mskDienthoai.Text == "( ) “;
{
MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskDienthoai.Focus();
return ;
}
if (mskNgaysinh.Text == " / /")
{
MessageBox.Show("Bạn phải nhập ngày sinh", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskNgaysinh.Focus();
return ;
}
if (!Functions.IsDate(mskNgaysinh.Text))
{
MessageBox.Show("Bạn phải nhập lại ngày sinh", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskNgaysinh.Text = "";
mskNgaysinh.Focus();
return ;
}
if (chkGioitinh.Checked == true)
gt = "Nam";

Bài giảng Cơ sở lập trình 2 147


else
gt = "Nữ";
sql = "SELECT Manhanvien FROM tblNhanvien WHERE
Manhanvien=N'" +
txtManhanvien.Text.Trim() + "'";
if (Functions.CheckKey(sql))
{
MessageBox.Show("Mã nhân viên này đã có, bạn phải nhập mã
khác", "Thông
báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtManhanvien.Focus();
txtManhanvien.Text = "";
return ;
}
sql = "INSERT INTO
tblNhanvien(Manhanvien,Tennhanvien,Gioitinh, Diachi,
Dienthoai, Ngaysinh) VALUES (N'" + txtManhanvien.Text.Trim() + "',N'" +
txtTennhanvien.Text.Trim() + "',N'" + gt + "',N'" + txtDiachi.Text.Trim()
+ "','" + mskDienthoai.Text + "','" +
Functions.ConvertDateTime(mskNgaysinh.Text) + "')";
Functions.RunSql(sql);
Load_DataGridView();
ResetValues();
btnXoa.Enabled = true;
btnThem.Enabled = true;
btnSua.Enabled = true;
btnBoqua.Enabled = false;
btnLuu.Enabled = false;
txtManhanvien.Enabled = false;
}

Với IsDate và ConvertDateTime là các hàm toàn cục được viết trong lớp Functions.

IsDate có tác dụng kiểm tra một biến có ở dạng ngày tháng không, ConvertDateTime có tác dụng
đổi một chuỗi ngày tháng do người dùng nhập có dạng dd/mm/yyyy thành chuỗi ngày tháng có dạng
mm/dd/yyyy để lưu vào CSDL.

6.2.8. Viết hàm IsDate

Mở cửa sổ code của lớp Functions và gõ vào đoạn mã lệnh như sau:

public static bool IsDate(string d)


{
string[] parts = d.Split('/');
if ((Convert.ToInt32(parts[0]) >= 1) &&
(Convert.ToInt32(parts[0]) <= 31) &&

Bài giảng Cơ sở lập trình 2 148


(Convert.ToInt32(parts[1]) >= 1) && (Convert.ToInt32(parts[1]) <= 12) &&
(Convert.ToInt32(parts[2]) >= 1900))
return true;
else
return false;
}

6.2.9. Viết hàm ConvertDateTime

Mở cửa sổ code của lớp Functions và gõ vào đoạn mã lệnh như sau:

public static string ConvertDateTime(string d)


{
string[] parts = d.Split('/');
string dt = String.Format("{0}/{1}/{2}", parts[1], parts[0],
parts[2]);
return dt;
}

6.2.10.Viết thủ tục btnSua_Click


private void btnSua_Click(object sender, EventArgs e)
{
string sql,gt;
if (tblNV.Rows.Count == 0 )
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return ;
}
if (txtManhanvien.Text == "" )
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return ;
}
if (txtTennhanvien.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập tên nhân viên", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtTennhanvien.Focus();
return ;
}
if (txtDiachi.Text.Trim().Length == 0)
Bài giảng Cơ sở lập trình 2 149
{
MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtDiachi.Focus();
return ;
}
if (mskDienthoai.Text == "( ) -")
{
MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskDienthoai.Focus();
return ;
}
if (mskNgaysinh.Text == " / /")
{
MessageBox.Show("Bạn phải nhập ngày sinh", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskNgaysinh.Focus();
return ;
}
if (!Functions.IsDate(mskNgaysinh.Text))
{
MessageBox.Show("Bạn phải nhập lại ngày sinh", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskNgaysinh.Text = "";
mskNgaysinh.Focus();
return ;
}
if (chkGioitinh.Checked == true)
gt = "Nam";
else
gt = "Nữ";
sql = "UPDATE tblNhanvien SET Tennhanvien=N'" +
txtTennhanvien.Text.Trim().ToString() +
"',Diachi=N'" + txtDiachi.Text.Trim().ToString() +
"',Dienthoai='" + mskDienthoai.Text.ToString() +
"',Gioitinh=N'" + gt +
"',Ngaysinh='" +
Functions.ConvertDateTime(mskNgaysinh.Text) +
"' WHERE Manhanvien=N'" + txtManhanvien.Text + "'";
Functions.RunSql(sql);
Load_DataGridView();
ResetValues();

Bài giảng Cơ sở lập trình 2 150


btnBoqua.Enabled = false;
}

6.2.11.Viết thủ tục btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
{
string sql;
if (tblNV.Rows.Count == 0)
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
if (txtManhanvien.Text == "")
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (MessageBox.Show("Bạn có muốn xóa không?", "Thông báo",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
sql = "DELETE tblNhanvien WHERE Manhanvien=N'" +
txtManhanvien.Text + "'";
Functions.RunSqlDel(sql);
Load_DataGridView();
ResetValues();
}
}

6.2.12.Viết thủ tục btnBoqua_Click


private void btnBoqua_Click(object sender, EventArgs e)
{
ResetValues();
btnBoqua.Enabled = false;
btnThem.Enabled = true;
btnXoa.Enabled = true;
btnSua.Enabled = true;
btnLuu.Enabled = false;
txtManhanvien.Enabled = false;
}

6.2.13.Viết thủ tục dùng phím Enter thay cho phím Tab
Bài giảng Cơ sở lập trình 2 151
private void txtManhanvien_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
SendKeys.Send("{TAB}");
}

Thực hiện tương tự cho txtTennhanvien.KeyUp, txtDiachi.KeyUp, mskDienthoai.KeyUp,


mskNgaysinh.KeyUp.

6.2.14.Viết thủ tục btnDong_Click


private void btnDong_Click(object sender, EventArgs e)
{
this.Close();
}

7. Xây dựng Form cập nhật danh mục Khách hàng

Mở một Form mới đặt tên là frmDMKhachhang rồi lưu vào thư mục Forms.

Bài giảng Cơ sở lập trình 2 152


Hình 64. Giao diện form Khách hàng

Form frmDMKhachhang cho phép thêm, xem, xoá, sửa danh sách các khách hàng trong bảng
tblKhach.

7.1. Tạo giao diện Form frmDMKhachhang

Điều khiển Name Text


Form frmDMKhachhang DANH MUC KHACH HANG
TextBox txtMakhach
txtTenkhach
txtDiachi
Button btnThem, btnXoa, btnSua, btnLuu, btnBoqua, btnDong
CheckBox chkGioitinh Nam
MaskedTextBox mskDienthoai Mask: Phone Number
DataGridView DataGridView

7.2. Viết mã lệnh Form frmDMKhachhang

7.2.1. Khai báo các lớp tham chiếu


using System.Data;
using System.Data.SqlClient;
using Quanlybanhang.Class;

// Khai báo biến toàn cục


DataTable tblKH;

7.2.2. Viết thủ tục FormLoad


private void frmDMKhachhang_Load(object sender, EventArgs e)
{
txtMakhach.Enabled = false;
btnLuu.Enabled = false;
btnBoqua.Enabled = false;
Load_DataGridView();
}

7.2.3. Viết thủ tục Load_DataGridView


private void Load_DataGridView()
{

Bài giảng Cơ sở lập trình 2 153


string sql;
sql = "SELECT Makhach, Tenkhach, Diachi, Dienthoai FROM
tblKhach";
tblKH = Functions.GetDataToTable(sql);
DataGridView.DataSource = tblKH;
DataGridView.Columns[0].HeaderText = "Mã khách";
DataGridView.Columns[1].HeaderText = "Tên khách";
DataGridView.Columns[2].HeaderText = "Địa chỉ";
DataGridView.Columns[3].HeaderText = "Điện thoại";
DataGridView.Columns[0].Width = 100;
DataGridView.Columns[1].Width = 150;
DataGridView.Columns[2].Width = 150;
DataGridView.Columns[3].Width = 150;
DataGridView.AllowUserToAddRows = false;
DataGridView.EditMode =
DataGridViewEditMode.EditProgrammatically;
}

7.2.4. Viết thủ tục DataGridView_Click


private void DataGridView_Click(object sender, EventArgs e)
{
if (btnThem.Enabled == false)
{
MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtMakhach.Focus();
return;
}
if (tblKH.Rows.Count == 0)
{
MessageBox.Show("Không có dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
txtMakhach.Text =
DataGridView.CurrentRow.Cells["Makhach"].Value.ToString();
txtTenkhach.Text =
DataGridView.CurrentRow.Cells["Tenkhach"].Value.ToString();
txtDiachi.Text =
DataGridView.CurrentRow.Cells["Diachi"].Value.ToString();
mskDienthoai.Text =
DataGridView.CurrentRow.Cells["Dienthoai"].Value.ToString();
btnSua.Enabled = true;

Bài giảng Cơ sở lập trình 2 154


btnXoa.Enabled = true;
btnBoqua.Enabled = true;
}

7.2.5. Viết thủ tục btnThem_Click

private void btnThem_Click(object sender, EventArgs e)


{
btnSua.Enabled = false;
btnXoa.Enabled = false;
btnBoqua.Enabled = true;
btnLuu.Enabled = true;
btnThem.Enabled = false;
ResetValues();
txtMakhach.Enabled = true;
txtMakhach.Focus();
}

7.2.6. Viết thủ tục ResetValues


private void ResetValues()
{
txtMakhach.Text = "";
txtTenkhach.Text = "";
txtDiachi.Text = "";
mskDienthoai.Text = "";
}

7.2.7. Viết thủ tục btnLuu_Click


private void btnLuu_Click(object sender, EventArgs e)
{
string sql;
if (txtMakhach.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập mã khách", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtMakhach.Focus();
return;
}
if (txtTenkhach.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập tên khách", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtTenkhach.Focus();
Bài giảng Cơ sở lập trình 2 155
return;
}
if (txtDiachi.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtDiachi.Focus();
return;
}
if (mskDienthoai.Text == "( ) -")
{
MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskDienthoai.Focus();
return;
}
sql = "SELECT Makhach FROM tblKhach WHERE Makhach=N'" +
txtMakhach.Text.Trim() + "'";
if (Functions.CheckKey(sql))
{
MessageBox.Show("Mã khách này đã có, bạn phải nhập mã
khác", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtMakhach.Focus();
txtMakhach.Text = "";
return;
}
sql = "INSERT INTO
tblKhach(Makhach,Tenkhach,Diachi,Dienthoai) VALUES (N'" +
txtMakhach.Text.Trim() + "',N'" + txtTenkhach.Text.Trim() + "',N'" +
txtDiachi.Text.Trim() + "','" + mskDienthoai.Text + "')";
Functions.RunSql(sql);
Load_DataGridView();
ResetValues();
btnXoa.Enabled = true;
btnThem.Enabled = true;
btnSua.Enabled = true;
btnBoqua.Enabled = false;
btnLuu.Enabled = false;
txtMakhach.Enabled = false;
}

7.2.8. Viết thủ tục btnSua_Click

Bài giảng Cơ sở lập trình 2 156


private void btnSua_Click(object sender, EventArgs e)
{
string sql;
if (tblKH.Rows.Count == 0)
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
if (txtMakhach.Text == "")
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (txtTenkhach.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập tên khách", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtTenkhach.Focus();
return;
}
if (txtDiachi.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtDiachi.Focus();
return;
}
if (mskDienthoai.Text == "( ) -")
{
MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
mskDienthoai.Focus();
return;
}
sql = "UPDATE tblKhach SET Tenkhach=N'" +
txtTenkhach.Text.Trim().ToString()
+ "',Diachi=N'" + txtDiachi.Text.Trim().ToString() +
"',Dienthoai='" +
mskDienthoai.Text.ToString() + "' WHERE Makhach=N'" +
txtMakhach.Text + "'";
Functions.RunSql(sql);

Bài giảng Cơ sở lập trình 2 157


Load_DataGridView();
ResetValues();
btnBoqua.Enabled = false;
}

7.2.9. Viết thủ tục btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
{
string sql;
if (tblKH.Rows.Count == 0)
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
if (txtMakhach.Text == "")
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (MessageBox.Show("Bạn có muốn xóa không?", "Thông báo",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
sql = "DELETE tblKhach WHERE Makhach=N'" +
txtMakhach.Text + "'";
Functions.RunSqlDel(sql);
Load_DataGridView();
ResetValues();
}
}

7.2.10. Viết thủ tục btnBoqua_Click


private void btnBoqua_Click(object sender, EventArgs e)
{
ResetValues();
btnBoqua.Enabled = false;
btnThem.Enabled = true;
btnXoa.Enabled = true;
btnSua.Enabled = true;
btnLuu.Enabled = false;
txtMakhach.Enabled = false;
}
Bài giảng Cơ sở lập trình 2 158
7.2.11. Viết thủ tục dùng phím Enter thay cho phím Tab
private void txtMakhach_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
SendKeys.Send("{TAB}");
}

7.2.12. Viết thủ tục btnDong_Click


private void btnDong_Click(object sender, EventArgs e)
{
this.Close();
}

8. Xây dựng Form cập nhật danh mục Hàng

Mở một Form mới đặt tên là frmDMHang rồi lưu vào thư mục Forms.

Form frmDMHang cho phép thêm, xem, xoá, sửa danh sách các hàng trong bảng tblHang.

8.1. Tạo giao diện Form frmDMHang

Điều khiển Name Text


Form frmDMHang DANH MUC HANG HOA
TextBox txtMahang, txtTenhang, txtSoluong, txtDongianhap,
txtDongiaban, txtAnh, txtGhichu.
ComboBox cboMachatlieu
PictureBox picAnh
DataGridView DataGridView
Button btnThem, btnXoa, btnSua, btnLuu, btnBoqua,
btnTimkiem, btnHienthi, btnDong, btnOpen.

Bài giảng Cơ sở lập trình 2 159


Hình 65. Giao diện form Hàng

8.2. Viết mã lệnh Form frmDMHang

8.2.1. Khai báo các lớp tham chiếu


using System.Data;
using System.Data.SqlClient;
using Quanlybanhang.Class;
// Khai báo biến toàn cục
DataTable tblH;

8.2.2. Viết thủ tục FormLoad


private void frmDMHang_Load(object sender, EventArgs e)
{
txtMahang.Enabled = false;

Bài giảng Cơ sở lập trình 2 160


btnLuu.Enabled = false;
btnBoqua.Enabled = false;
Load_DataGridView();
Functions.FillCombo("SELECT Machatlieu, Tenchatlieu FROM
tblChatlieu",
cboMachatlieu, "Machatlieu", "Tenchatlieu");
cboMachatlieu.SelectedIndex = -1;
ResetValues();
}

Với FillCombo là một thủ tục toàn cục được viết trong Class Functions, có tác dụng lấy dữ liệu từ
một câu lệnh SQL đổ vào một ComboBox.

8.2.3. Viết thủ tục FillCombo

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

public static void FillCombo(string sql, ComboBox cbo, string ma,


string ten)
{
SqlDataAdapter Mydata =new SqlDataAdapter(sql,
Functions.Conn);
DataTable table = new DataTable();
Mydata.Fill(table);
cbo.DataSource = table;

cbo.ValueMember = ma; // Truong gia tri


cbo.DisplayMember = ten; // Truong hien thi
}

8.2.4. Viết thủ tục ResetValues


private void ResetValues()
{
txtMahang.Text = "";
txtTenhang.Text = "";
cboMachatlieu.Text = "";
txtSoluong.Text = "0";
txtDongianhap.Text = "0";
txtDongiaban.Text = "0";
txtSoluong.Enabled = false;
txtDongianhap.Enabled = false;
txtDongiaban.Enabled = false;
txtAnh.Text = "";
picAnh.Image = null;
txtGhichu.Text = "";

Bài giảng Cơ sở lập trình 2 161


}
8.2.5. Viết thủ tục Load_DataGridView
private void Load_DataGridView()
{
string sql;
sql = "SELECT Mahang, Tenhang, Machatlieu, Soluong,
Dongianhap, Dongiaban FROM
tblHang";
tblH = Functions.GetDataToTable(sql);
DataGridView.DataSource = tblH;
DataGridView.Columns[0].HeaderText = "Mã hàng";
DataGridView.Columns[1].HeaderText = "Tên hàng";
DataGridView.Columns[2].HeaderText = "Chất liệu";
DataGridView.Columns[3].HeaderText = "Số lượng";
DataGridView.Columns[4].HeaderText = "Đơn giá nhập";
DataGridView.Columns[5].HeaderText = "Đơn giá bán";
DataGridView.Columns[0].Width = 80;
DataGridView.Columns[1].Width = 140;
DataGridView.Columns[2].Width = 80;
DataGridView.Columns[3].Width = 80;
DataGridView.Columns[4].Width = 100;
DataGridView.Columns[5].Width = 100;
DataGridView.AllowUserToAddRows = false;
DataGridView.EditMode =
DataGridViewEditMode.EditProgrammatically;
}

8.2.6. Viết thủ tục DataGridView_Click


private void DataGridView_Click(object sender, EventArgs e)
{
string ma;
if (btnThem.Enabled == false)
{
MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtMahang.Focus();
return;
}
if (tblH.Rows.Count == 0)
{
MessageBox.Show("Không có dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);

Bài giảng Cơ sở lập trình 2 162


return;
}
txtMahang.Text =
DataGridView.CurrentRow.Cells["Mahang"].Value.ToString();
txtTenhang.Text =
DataGridView.CurrentRow.Cells["Tenhang"].Value.ToString();
ma =
DataGridView.CurrentRow.Cells["Machatlieu"].Value.ToString();
cboMachatlieu.Text = Functions.GetFieldValues("SELECT
Tenchatlieu FROM
tblChatlieu WHERE Machatlieu = N'" + ma + "'");

txtSoluong.Text =
DataGridView.CurrentRow.Cells["Soluong"].Value.ToString();
txtDongianhap.Text =
DataGridView.CurrentRow.Cells["Dongianhap"].Value.ToString();
txtDongiaban.Text =
DataGridView.CurrentRow.Cells["Dongiaban"].Value.ToString();
txtAnh.Text = Functions.GetFieldValues("SELECT Anh FROM
tblHang WHERE Mahang =
N'" + txtMahang.Text + "'");
picAnh.Image = Image.FromFile(txtAnh.Text);
txtGhichu.Text = Functions.GetFieldValues("SELECT Ghichu FROM
tblHang WHERE
Mahang = N'" + txtMahang.Text + "'");
btnSua.Enabled = true;
btnXoa.Enabled = true;
btnBoqua.Enabled = true;
}

Với GetFieldValues là một hàm toàn cục được viết trong Class Functions, có tác dụng lấy dữ liệu từ
một câu lệnh SQL.

8.2.7. Viết hàm GetFieldValues

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

public static string GetFieldValues(string sql)


{
string ma = "";
SqlCommand cmd = new SqlCommand(sql, Functions.Conn);
SqlDataReader reader ;
reader = cmd.ExecuteReader();
while (reader.Read())
{
ma = reader.GetValue(0).ToString();
Bài giảng Cơ sở lập trình 2 163
}
reader.Close();
return ma;
}

8.2.8. Tìm hiểu đối tượng SqlDataReader

SqlCommand thực thi câu lệnh Sql SELECT và trả về tập dữ liệu SqlDataReader. Dữ liệu trong
SqlDataReader được lưu trữ dưới dạng các dòng và các cột, ta chỉ có thể duyệt dữ liệu theo một
chiều từ đầu đến cuối.

Để đọc từng dòng dữ liệu trong SqlDataReader ta sử dụng phương thức Read với cú pháp như sau:

reader.Read();

SqlDataReader không cung cấp cách thức cho phép kiểm soát số bản ghi đang nắm giữ mà quy định
phương thức Read() trả về giá trị True nếu vẫn tồn tại bản ghi kế tiếp. Do đó để duyệt qua danh sách
tất cả các bản ghi ta có thể sử dụng vòng lặp while.

Để đọc dữ liệu của từng cột ta sử dụng phương thức GetValue với cú pháp như sau:

reader.GetValue(FieldIndex);

với FieldIndex là số thứ tự của cột muốn lấy dữ liệu (bắt đầu từ 0). Ngoài ra nếu biết rõ kiểu dữ liệu
của cột cần lấy dữ liệu ta có thể sử dụng các phương thức gọi tường minh như: GetString(),
GetInt32()… khi đó tốc độ đọc sẽ nhanh hơn.

8.2.9. Viết thủ tục btnThem_Click


private void btnThem_Click(object sender, EventArgs e)
{
btnSua.Enabled = false;
btnXoa.Enabled = false;
btnBoqua.Enabled = true;
btnLuu.Enabled = true;
btnThem.Enabled = false;
ResetValues();
txtMahang.Enabled = true;
txtMahang.Focus();
}

8.2.10. Viết thủ tục btnLuu_Click


private void btnLuu_Click(object sender, EventArgs e)
{
string sql;
if (txtMahang.Text.Trim().Length == 0)

Bài giảng Cơ sở lập trình 2 164


{
MessageBox.Show("Bạn phải nhập mã hàng", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtMahang.Focus();
return;
}
if (txtTenhang.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập tên hàng", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtTenhang.Focus();
return;
}
if (cboMachatlieu.Text.Trim().Length == 0 )
{
MessageBox.Show("Bạn phải nhập chất liệu", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
cboMachatlieu.Focus();
return;
}
if (txtAnh.Text.Trim().Length == 0 )
{
MessageBox.Show("Bạn phải chọn ảnh minh họa cho hàng",
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtAnh.Focus();
return;
}
sql = "SELECT Mahang FROM tblHang WHERE Mahang=N'" +
txtMahang.Text.Trim() + "'";
if (Functions.CheckKey(sql))
{
MessageBox.Show("Mã hàng này đã có, bạn phải nhập mã
khác", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtMahang.Focus();
txtMahang.Text = "";
return;
}
sql = "INSERT INTO
tblHang(Mahang,Tenhang,Machatlieu,Soluong,Dongianhap,
Dongiaban,Anh,Ghichu) VALUES(N'" + txtMahang.Text.Trim() +

Bài giảng Cơ sở lập trình 2 165


"',N'" + txtTenhang.Text.Trim() + "',N'" +
cboMachatlieu.SelectedValue.ToString() + "'," + txtSoluong.Text.Trim() +
"," + txtDongianhap.Text + "," + txtDongiaban.Text +
",'" + txtAnh.Text + "',N'" + txtGhichu.Text.Trim() + "')";
Functions.RunSql(sql);
Load_DataGridView();
ResetValues();
btnXoa.Enabled = true;
btnThem.Enabled = true;
btnSua.Enabled = true;
btnBoqua.Enabled = false;
btnLuu.Enabled = false;
txtMahang.Enabled = false;
}

8.2.11. Viết thủ tục btnSua_Click


private void btnSua_Click(object sender, EventArgs e)
{
string sql;
if (tblH.Rows.Count == 0)
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
if (txtMahang.Text == "")
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (txtTenhang.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập tên hàng", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtTenhang.Focus();
return;
}
if (cboMachatlieu.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải nhập chất liệu", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);

Bài giảng Cơ sở lập trình 2 166


cboMachatlieu.Focus();
return;
}
if (txtAnh.Text.Trim().Length == 0)
{
MessageBox.Show("Bạn phải chọn ảnh minh họa cho hàng",
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtAnh.Focus();
return;
}
sql = "UPDATE tblHang SET Tenhang=N'" +
txtTenhang.Text.Trim().ToString() +
"',Machatlieu=N'" +
cboMachatlieu.SelectedValue.ToString() +
"',Anh='" + txtAnh.Text +
"',Ghichu=N'" + txtGhichu.Text + "' WHERE Mahang=N'" +
txtMahang.Text + "'";
Functions.RunSql(sql);
Load_DataGridView();
ResetValues();
btnBoqua.Enabled = false;
}

8.2.12. Viết thủ tục btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
{
string sql;
if (tblH.Rows.Count == 0)
{
MessageBox.Show("Không còn dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
if (txtMahang.Text == "")
{
MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (MessageBox.Show("Bạn có muốn xóa không?", "Thông báo",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{

Bài giảng Cơ sở lập trình 2 167


sql = "DELETE tblHang WHERE Mahang=N'" + txtMahang.Text +
"'";
Functions.RunSqlDel(sql);
Load_DataGridView();
ResetValues();
}
}

8.2.13. Viết thủ tục btnBoqua_Click


private void btnBoqua_Click(object sender, EventArgs e)
{
ResetValues();
btnBoqua.Enabled = false;
btnThem.Enabled = true;
btnXoa.Enabled = true;
btnSua.Enabled = true;
btnLuu.Enabled = false;
txtMahang.Enabled = false;
}

8.2.14. Viết thủ tục btnOpen_Click


private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog dlgOpen = new OpenFileDialog();
dlgOpen.Filter = "bitmap(*.bmp)|*.bmp|Gif(*.gif)|*.gif|All
files(*.*)|*.*";
dlgOpen.InitialDirectory = "D:\\";
dlgOpen.FilterIndex = 2;
dlgOpen.Title = "Chon hinh anh de hien thi";
if (dlgOpen.ShowDialog() == DialogResult.OK)
{
picAnh.Image = Image.FromFile(dlgOpen.FileName);
txtAnh.Text = dlgOpen.FileName;
}
}

8.2.15. Viết thủ tục btnTimkiem_Click

Thủ tục tìm kiếm cho phép tìm các bản ghi thỏa mãn một số điều kiện nào đấy và hiển thị kết quả
tìm được vào lưới DataGridView.

private void btnTimkiem_Click(object sender, EventArgs e)


{
string sql;

Bài giảng Cơ sở lập trình 2 168


if ((txtMahang.Text == "") && (txtTenhang.Text == "") &&
(cboMachatlieu.Text ==
""))
{
MessageBox.Show("Hãy nhập một điều kiện tìm kiếm!!!",
"Yêu cầu ...",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
sql = "SELECT * FROM tblHang WHERE 1=1";
if (txtMahang.Text != "")
sql = sql + " AND Mahang Like N'%" + txtMahang.Text + "%'";
if (txtTenhang.Text != "")
sql = sql + " AND Tenhang Like N'%" + txtTenhang.Text + "%'";
if (cboMachatlieu.Text != "")
sql = sql + " AND Machatlieu Like N'%" + cboMachatlieu.SelectedValue +
"%'";
tblH = Functions.GetDataToTable(sql);
if (tblH.Rows.Count == 0 )
MessageBox.Show("Không có bản ghi thỏa mãn điều kiện!!!",
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
else
MessageBox.Show("Có " + tblH.Rows.Count + " bản ghi thỏa
mãn điều kiện!!!",
"Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);

DataGridView.DataSource = tblH;
ResetValues();
}

8.2.16. Viết thủ tục btnHienthi_Click


Thủ tục có tác dụng hiển thị toàn bộ danh sách các mặt hàng có trong cơ sở dữ liệu lên lưới.

private void btnHienthi_Click(object sender, EventArgs e)


{
string sql;
sql = "SELECT Mahang, Tenhang, Machatlieu, Soluong,
Dongianhap, Dongiaban, Anh,
Ghichu FROM tblHang";
tblH = Functions.GetDataToTable(sql);
DataGridView.DataSource = tblH;
}

Bài giảng Cơ sở lập trình 2 169


9. Xây dựng Form cập nhật Hóa đơn bán

Mở một Form mới đặt tên là frmHoadonBan và lưu vào thư mục Forms.

Form frmHoadonBan cho phép thêm, xem, xoá danh sách các hóa đơn và các mặt hàng có trong
bảng tblHDBan và tblChitietHDBan.

Hình 66. Giao diện form Hoá đơn bán

Ngoài ra form này cho phép chúng ta kết xuất các thông tin trong hóa đơn ra một tệp Excel thông
qua nút lệnh In hóa đơn. Để làm được điều này ta phải tham chiếu tới đối tượng COM của Excel do
Microsoft Visual Studio cung cấp. COM là một đối tượng đóng gói theo 1 chuẩn do Microsoft
Visual Studio định ra và nó có khả năng chạy được trên nhiều nền tảng ứng dụng khác nhau.

9.1. Tham chiếu thư viện Microsoft.Office.Interop.Excel


Bài giảng Cơ sở lập trình 2 170
 Vào menu Project/Add Reference… xuất hiện hộp hội thoại Add Reference.

 Chọn tab COM, kích chọn Microsoft Excel 14.0 Object Library rồi chọn OK.

Hình 67. Tham chiếu thư viện Excel

9.2. Tạo giao diện Form frmHoadonBan

Điều khiển Name Text


Form frmHoadonBan HOA DON BAN
Label lblBangchu Bằng chữ:
TextBox txtMaHDBan, txtNgayban, txtTennhanvien,txtTenkhach,
txtDiachi, txtDienthoai, txtTongtien, txtTenhang,
txtDongiabakn, txtSoluong, txtGiamgia, txtThanhtien.
ComboBox cboManhanvien, cboMakhach, cboMahang, cboMaHDBan.
DataGridView DataGridViewChitiet
Button btnNgay, btnThemmoi, btnLuu, btnXoa, btnInhoadon,
btnDong, btnTimkiem

9.3. Viết mã lệnh Form frmDMHoadonBan

9.3.1. Khai báo các lớp tham chiếu


using System.Data.SqlClient;
Bài giảng Cơ sở lập trình 2 171
using COMExcel = Microsoft.Office.Interop.Excel;
//using Quanlybanhang.Class;

DataTable tblCTHDB;

9.3.2. Viết thủ tục FormLoad


private void frmHoadonban_Load(object sender, EventArgs e)
{
btnThemmoi.Enabled = true;
btnLuu.Enabled = false;
btnXoaHD.Enabled = false;
btnInhoadon.Enabled = false;
txtMaHDBan.ReadOnly = true;
txtTennhanvien.ReadOnly = true;
txtTenkhach.ReadOnly = true;
txtDiachi.ReadOnly = true;
txtDienthoai.ReadOnly = true;
txtTenhang.ReadOnly = true;
txtDongiaban.ReadOnly = true;
txtThanhtien.ReadOnly = true;
txtTongtien.ReadOnly = true;
txtGiamgia.Text = "0";
txtTongtien.Text = "0";
Functions.FillCombo("SELECT Makhach, Tenkhach FROM
tblKhach",cboMakhach,
"Makhach", "Tenkhach");
cboMakhach.SelectedIndex = -1;
Functions.FillCombo("SELECT Manhanvien, Tennhanvien FROM
tblNhanvien",
cboManhanvien, "Manhanvien", "Tennhanvien");
cboManhanvien.SelectedIndex = -1;
Functions.FillCombo("SELECT Mahang, Tenhang FROM
tblHang",cboMahang,
"Mahang","Tenhang");
cboMahang.SelectedIndex = -1;

= các sách còn thiếu phần này:


Functions.FillCombo("SELECT Mahdban FROM tblChitiethdban",
cboMaHDBan,
"Mahdban", "Mahdban");
cboMaHDBan.SelectedIndex = -1;

//Hiển thị thông tin của một hóa đơn được gọi từ form tìm kiếm
if (txtMaHDBan.Text != "")
Bài giảng Cơ sở lập trình 2 172
{
Load_ThongtinHD();
btnXoaHD.Enabled = true;
btnInhoadon.Enabled = true;
}
Load_DataGridViewChitiet();
}

9.3.3. Viết thủ tục Load_DataGridViewChitiet


private void Load_DataGridViewChitiet()
{
string sql;
sql = "SELECT a.Mahang, b.Tenhang, a.Soluong, b.Dongiaban,
a.Giamgia,
a.Thanhtien FROM tblChitietHDBan AS a, tblHang AS b WHERE a.MaHDBan = N'"
+
txtMaHDBan.Text + "' AND a.Mahang=b.Mahang";
tblCTHDB = Functions.GetDataToTable(sql);
DataGridViewChitiet.DataSource = tblCTHDB;

DataGridViewChitiet.Columns[0].HeaderText = "Mã hàng";


DataGridViewChitiet.Columns[1].HeaderText = "Tên hàng";
DataGridViewChitiet.Columns[2].HeaderText = "Số lượng";
DataGridViewChitiet.Columns[3].HeaderText = "Đơn giá";
DataGridViewChitiet.Columns[4].HeaderText = "Giảm giá %";
DataGridViewChitiet.Columns[5].HeaderText = "Thành tiền";
DataGridViewChitiet.Columns[0].Width = 80;
DataGridViewChitiet.Columns[1].Width = 100;
DataGridViewChitiet.Columns[2].Width = 80;
DataGridViewChitiet.Columns[3].Width = 90;
DataGridViewChitiet.Columns[4].Width = 90;
DataGridViewChitiet.Columns[5].Width = 90;
DataGridViewChitiet.AllowUserToAddRows = false;
DataGridViewChitiet.EditMode =
DataGridViewEditMode.EditProgrammatically;
}

9.3.4. Viết thủ tục Load_ThongtinHD()


private void Load_ThongtinHD()
{
Bài giảng Cơ sở lập trình 2 173
string str;
str = "SELECT Ngayban FROM tblHDBan WHERE MaHDBan = N'" +
txtMaHDBan.Text + "'";
txtNgayban.Text =
Functions.ConvertDateTime(Functions.GetFieldValues(str));
str = "SELECT Manhanvien FROM tblHDBan WHERE MaHDBan = N'" +
txtMaHDBan.Text + "'";
cboManhanvien.Text = Functions.GetFieldValues(str);

str = "SELECT Makhach FROM tblHDBan WHERE MaHDBan = N'" +


txtMaHDBan.Text + "'";
cboMakhach.Text = Functions.GetFieldValues(str);

str = "SELECT Tongtien FROM tblHDBan WHERE MaHDBan = N'" +


txtMaHDBan.Text + "'";
txtTongtien.Text = Functions.GetFieldValues(str);

lblBangchu.Text = "Bằng chữ: " +


Functions.ChuyenSoSangChu(txtTongtien.Text);
}

9.3.5. Viết thủ tục btnThemmoi_Click


private void btnThemmoi_Click(object sender, EventArgs e)
{
btnXoaHD.Enabled = false;
btnLuu.Enabled = true;
btnInhoadon.Enabled = false;
btnThemmoi.Enabled = false;
ResetValues();
txtMaHDBan.Text = Functions.CreateKey("HDB");
Load_DataGridViewChitiet();
}

Với CreateKey là một hàm toàn cục được viết trong Class Functions, có tác dụng sinh khóa tự động
cho Mã hóa đơn bán.

9.3.6. Viết hàm CreateKey

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

//Hàm tạo khóa có dạng: TientoNgaythangnam_giophutgiay


public static string CreateKey(string tiento )
{
string key = tiento;
string[] partsDay;

Bài giảng Cơ sở lập trình 2 174


partsDay = DateTime.Now.ToShortDateString().Split('/');
//Ví dụ 07/08/2009
string d = String.Format("{0}{1}{2}", partsDay[0],
partsDay[1], partsDay[2]);
key = key + d;
string[] partsTime;
partsTime = DateTime.Now.ToLongTimeString().Split(':');
//Ví dụ 7:08:03 PM hoặc 7:08:03 AM
if( partsTime[2].Substring(3, 2) == "PM" )
partsTime[0] = ConvertTimeTo24(partsTime[0]);
if( partsTime[2].Substring(3, 2) == "AM" )
if( partsTime[0].Length == 1 )
partsTime[0] = "0" + partsTime[0];
//Xóa ký tự trắng và PM hoặc AM
partsTime[2] = partsTime[2].Remove(2, 3);
string t;
t= String.Format("{0}{1}{2}", partsTime[0], partsTime[1],
partsTime[2]);
key = key + t;
return key;
}

Với ConvertTimeTo24 là một hàm toàn cục được viết trong Class Functions, có tác dụng chuyển đổi
giờ từ dạng PM sang dạng 24h.

9.3.7. Viết hàm ConvertTimeTo24

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

public static string ConvertTimeTo24(string hour)


{
string h = "";
switch (hour)
{
case "1":
h = "13";
break;
case "2":
h = "14";
break;
case "3":
h = "15";
break;
case "4":
h = "16";
break;
Bài giảng Cơ sở lập trình 2 175
case "5":
h = "17";
break;
case "6":
h = "18";
break;
case "7":
h = "19";
break;
case "8":
h = "20";
break;
case "9":
h = "21";
break;
case "10":
h = "22";
break;
case "11":
h = "23";
break;
case "12":
h = "0";
break;
}
return h;
}

9.3.8. Viết thủ tục ResetValues


private void ResetValues()
{
txtMaHDBan.Text = "";
txtNgayban.Text = DateTime.Now.ToShortDateString();
cboManhanvien.Text = "";
cboMakhach.Text = "";
txtTongtien.Text = "0";
lblBangchu.Text = "Bằng chữ: ";
cboMahang.Text = "";
txtSoluong.Text = "";
txtGiamgia.Text = "0";
txtThanhtien.Text = "0";
}

9.3.9. Viết thủ tục btnLuu_Click

Bài giảng Cơ sở lập trình 2 176


private void btnLuu_Click(object sender, EventArgs e)
{
string sql;
double sl, SLcon, tong, Tongmoi;
sql = "SELECT MaHDBan FROM tblHDBan WHERE MaHDBan=N'" +
txtMaHDBan.Text + "'";
if(!Functions.CheckKey(sql) )
{
// Mã hóa đơn chưa có, tiến hành lưu các thông tin chung
// Mã HDBan được sinh tự động do đó không có trường hợp
trùng khóa
if( txtNgayban.Text.Length == 0 )
{
MessageBox.Show("Bạn phải nhập ngày bán", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtNgayban.Focus();
return ;
}
if( cboManhanvien.Text.Length == 0 )
{
MessageBox.Show("Bạn phải nhập nhân viên", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
cboManhanvien.Focus();
return;
}
if( cboMakhach.Text.Length == 0 )
{
MessageBox.Show("Bạn phải nhập khách hàng", "Thông
báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
cboMakhach.Focus();
return;
}
//lưu thông tin chung vào bảng tblhdban
sql = "INSERT INTO tblHDBan(MaHDBan, Ngayban, Manhanvien, Makhach,
Tongtien)
VALUES (N'" + txtMaHDBan.Text.Trim() + "','" +
Functions.ConvertDateTime(txtNgayban.Text.Trim())
+ "',N'" + cboManhanvien.SelectedValue + "',N'" +
cboMakhach.SelectedValue + "'," +
txtTongtien.Text + ")";
Functions.RunSql(sql);
}

Bài giảng Cơ sở lập trình 2 177


// Lưu thông tin của các mặt hàng
if( cboMahang.Text.Trim().Length == 0 )
{
MessageBox.Show("Bạn phải nhập mã hàng", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
cboMahang.Focus();
return;
}
if( (txtSoluong.Text.Trim().Length == 0) || (txtSoluong.Text
== "0" ))
{
MessageBox.Show("Bạn phải nhập số lượng", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtSoluong.Text = "";
txtSoluong.Focus();
return;
}
if( txtGiamgia.Text.Trim().Length == 0 )
{
MessageBox.Show("Bạn phải nhập giảm giá", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtGiamgia.Focus();
return;
}
sql = "SELECT Mahang FROM tblChitietHDBan WHERE MaHang=N'" +
cboMahang.SelectedValue + "' AND MaHDBan = N'" + txtMaHDBan.Text.Trim() +
"'";
if(Functions.CheckKey(sql))
{
MessageBox.Show("Mã hàng này đã có, bạn phải nhập mã
khác", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
ResetValuesHang();
cboMahang.Focus();
return;
}
// Kiểm tra xem số lượng hàng trong kho còn đủ để cung cấp
không?
sl = Convert.ToDouble(Functions.GetFieldValues("SELECT
Soluong FROM tblHang
WHERE Mahang = N'" + cboMahang.SelectedValue + "'"));

Bài giảng Cơ sở lập trình 2 178


if( Convert.ToDouble(txtSoluong.Text) > sl )
{
MessageBox.Show("Số lượng mặt hàng này chỉ còn " + sl,
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
txtSoluong.Text = "";
txtSoluong.Focus();
return;
}
sql = "INSERT INTO
tblChitietHDBan(MaHDBan,Mahang,Soluong,Dongia,Giamgia, Thanhtien)
VALUES(N'" + txtMaHDBan.Text.Trim() + "',N'" + cboMahang.SelectedValue +
"'," + txtSoluong.Text + ",," + txtSoluong.Text + "," + txtGiamgia.Text +
"," + txtThanhtien.Text + ")";
Functions.RunSql(sql);
Load_DataGridViewChitiet();
// Cập nhật lại số lượng của mặt hàng vào bảng tblHang
SLcon = sl - Convert.ToDouble(txtSoluong.Text);
sql = "UPDATE tblHang SET Soluong =" + SLcon + " WHERE
Mahang= N'" +
cboMahang.SelectedValue + "'";
Functions.RunSql(sql);
// Cập nhật lại tổng tiền cho hóa đơn bán

tong = Convert.ToDouble(Functions.GetFieldValues("SELECT
Tongtien FROM tblHDBan
WHERE MaHDBan = N'" + txtMaHDBan.Text + "'"));
Tongmoi = tong + Convert.ToDouble(txtThanhtien.Text);
sql = "UPDATE tblHDBan SET Tongtien =" + Tongmoi + " WHERE
MaHDBan = N'" +
txtMaHDBan.Text + "'";
Functions.RunSql(sql);
txtTongtien.Text = Tongmoi.ToString();
lblBangchu.Text = "Bằng chữ: " +
Functions.ChuyenSoSangChu(Tongmoi.ToString());
ResetValuesHang();
btnXoaHD.Enabled = true;
btnThemmoi.Enabled = true;
btnInhoadon.Enabled = true;
}

Với ChuyenSoSangChu là một hàm toàn cục được viết trong Class Functions, có tác dụng đọc từ
dạng số sang dạng chữ.

9.3.10. Viết hàm ChuyenSoSangChu

Bài giảng Cơ sở lập trình 2 179


Mở cửa sổ lớp Class Functions viết mã lệnh như sau:

public static string ChuyenSoSangChu(string sNumber)


{
int mLen, mDigit;
string mTemp = "";
string[] mNumText;
//Xóa các dấu "," nếu có
sNumber = sNumber.Replace(",","");
mNumText =
"không;một;hai;ba;bốn;năm;sáu;bảy;tám;chín".Split(';');
mLen = sNumber.Length - 1; // trừ 1 vì thứ tự đi từ 0
for (int i = 0; i <= mLen; i++)
{
mDigit = Convert.ToInt32(sNumber.Substring(i, 1));
mTemp = mTemp + " " + mNumText[mDigit];
if (mLen == i) // Chữ số cuối cùng không cần xét tiếp
break;
switch ((mLen - i) % 9)
{
case 0:
mTemp = mTemp + " tỷ";
if (sNumber.Substring(i + 1, 3) == "000")
i = i + 3;
if (sNumber.Substring(i + 1, 3) == "000")
i = i + 3;
if (sNumber.Substring(i + 1, 3) == "000")
i = i + 3;
break;
case 6:
mTemp = mTemp + " triệu";
if (sNumber.Substring(i + 1, 3) == "000")
i = i + 3;
if (sNumber.Substring(i + 1, 3) == "000")
i = i + 3;
break;
case 3:
mTemp = mTemp + " nghìn";
if (sNumber.Substring(i + 1, 3) == "000")
i = i + 3;
break;
default:
switch ((mLen - i) % 3)
{
case 2:

Bài giảng Cơ sở lập trình 2 180


mTemp = mTemp + " trăm";
break;
case 1:
mTemp = mTemp + " mươi";
break;
}
break;
}
}
//Loại bỏ trường hợp x00
mTemp = mTemp.Replace("không mươi không ", "");
mTemp = mTemp.Replace("không mươi không", "");
//Loại bỏ trường hợp 00x
mTemp = mTemp.Replace("không mươi ", "linh ");
//Loại bỏ trường hợp x0, x>=2
mTemp = mTemp.Replace("mươi không", "mươi");
//Fix trường hợp 10
mTemp = mTemp.Replace("một mươi", "mười");
//Fix trường hợp x4, x>=2
mTemp = mTemp.Replace("mươi bốn", "mươi tư");
//Fix trường hợp x04
mTemp = mTemp.Replace("linh bốn", "linh tư");
//Fix trường hợp x5, x>=2
mTemp = mTemp.Replace("mươi năm", "mươi lăm");
//Fix trường hợp x1, x>=2
mTemp = mTemp.Replace("mươi một", "mươi mốt");
//Fix trường hợp x15
mTemp = mTemp.Replace("mười năm", "mười lăm");
//Bỏ ký tự space
mTemp = mTemp.Trim();
//Viết hoa ký tự đầu tiên
mTemp = mTemp.Substring(0, 1).ToUpper() + mTemp.Substring(1)
+ " đồng";
return mTemp ;
}

9.3.11. Viết thủ tục ResetValuesHang


private void ResetValuesHang()
{
cboMahang.Text = "";
txtSoluong.Text = "";
txtGiamgia.Text = "0";
txtThanhtien.Text = "0";
}

Bài giảng Cơ sở lập trình 2 181


9.3.12. Viết thủ tục DataGridViewChitiet_CellDoubleClick

Thủ tục này cho phép người dùng kích đúp chuột vào một mặt hàng trong lưới để xóa.

private void DataGridViewChitiet_CellDoubleClick(object sender,


DataGridViewCellEventArgs e)
{
string mahang;
Double Thanhtien;
if(tblCTHDB.Rows.Count == 0 )
{
MessageBox.Show("Không có dữ liệu!", "Thông báo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return ;
}
if((MessageBox.Show("Bạn có chắc chắn muốn xóa không?",
"Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes))
{
//Xóa hàng và cập nhật lại số lượng hàng
mahang =
DataGridViewChitiet.CurrentRow.Cells["Mahang"].Value.ToString();
DelHang(txtMaHDBan.Text, mahang);
// Cập nhật lại tổng tiền cho hóa đơn bán
Thanhtien =
Convert.ToDouble(DataGridViewChitiet.CurrentRow.
Cells["Thanhtien"].Value.ToString());
DelUpdateTongtien(txtMaHDBan.Text, Thanhtien);
Load_DataGridViewChitiet();
}
}

9.3.13. Viết thủ tục DelHang


private void DelHang(string Mahoadon, string Mahang)
{
Double s, sl, SLcon;
string sql;
sql = "SELECT Soluong FROM tblChitietHDBan WHERE MaHDBan =
N'" + Mahoadon + "'
AND MaHang=N'" + Mahang + "'";
s = Convert.ToDouble(Functions.GetFieldValues(sql));
sql = "DELETE tblChitietHDBan WHERE MaHDBan=N'" + Mahoadon +
"' AND Mahang = N'"
+ Mahang + "'";
Bài giảng Cơ sở lập trình 2 182
Functions.RunSqlDel(sql);
// Cập nhật lại số lượng cho các mặt hàng
sql = "SELECT Soluong FROM tblHang WHERE Mahang = N'" +
Mahang + "'";
sl = Convert.ToDouble(Functions.GetFieldValues(sql));
SLcon = sl + s;
sql = "UPDATE tblHang SET Soluong =" +SLcon + " WHERE Mahang=
N'" +Mahang + "'";
Functions.RunSql(sql);
}

9.3.14. Viết thủ tục DelUpdateTongtien


private void DelUpdateTongtien(string Mahoadon, double Thanhtien)
{
Double Tong, Tongmoi;
string sql;
sql = "SELECT Tongtien FROM tblHDBan WHERE MaHDBan = N'" +
Mahoadon + "'";
Tong = Convert.ToDouble(Functions.GetFieldValues(sql));
Tongmoi = Tong - Thanhtien;
sql = "UPDATE tblHDBan SET Tongtien =" + Tongmoi + " WHERE
MaHDBan = N'" +
Mahoadon + "'";
Functions.RunSql(sql);
txtTongtien.Text = Tongmoi.ToString();
lblBangchu.Text = "Bằng chữ: " +
Functions.ChuyenSoSangChu(Tongmoi.ToString());
}

9.3.15. Viết thủ tục btnXoaHD_Click

Thủ tục này cho phép xóa toàn bộ thông tin của một hóa đơn

private void btnXoaHD_Click(object sender, EventArgs e)


{
if (MessageBox.Show("Bạn có chắc chắn muốn xóa không?",
"Thông báo",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
string[] Mahang = new string[20];
string sql;
int n = 0;
int i;
sql = "SELECT Mahang FROM tblChitietHDBan WHERE MaHDBan =
N'" +
Bài giảng Cơ sở lập trình 2 183
txtMaHDBan.Text + "'";
SqlCommand cmd = new SqlCommand(sql, Functions.Conn);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Mahang[n] = reader.GetString(0).ToString();
n = n + 1;
}
reader.Close();
//Xóa danh sách các mặt hàng của hóa đơn
for (i = 0 ; i <= n - 1; i++)
DelHang(txtMaHDBan.Text, Mahang[i]);
//Xóa hóa đơn
sql = "DELETE tblHDBan WHERE MaHDBan=N'" +
txtMaHDBan.Text + "'";
Functions.RunSqlDel(sql);
ResetValues();
Load_DataGridViewChitiet();
btnXoaHD.Enabled = false;
btnInhoadon.Enabled = false;
}
}

9.3.16. Viết thủ tục cboManhanvien_TextChanged


private void cboManhanvien_TextChanged(object sender, EventArgs e)
{
string str;
if (cboManhanvien.Text == "")
txtTennhanvien.Text = "";
// Khi kich chon Ma nhan vien thi ten nhan vien se tu dong
hien ra
str = "Select Tennhanvien from tblNhanvien where Manhanvien
=N'" +
cboManhanvien.SelectedValue + "'";
txtTennhanvien.Text = Functions.GetFieldValues(str);
}

9.3.17. Viết thủ tục cboMakhach_TextChanged


private void cboMakhach_TextChanged(object sender, EventArgs e)
{
string str;
if (cboMakhach.Text == "")
{
txtTenkhach.Text = "";
Bài giảng Cơ sở lập trình 2 184
txtDiachi.Text = "";
txtDienthoai.Text = "";
}
//Khi kich chon Ma khach thi ten khach, dia chi, dien thoai
se tu dong hien ra
str="Select Tenkhach from tblKhach where Makhach = N'" +
boMakhach.SelectedValue
+ "'";
txtTenkhach.Text = Functions.GetFieldValues(str);
str ="Select Diachi from tblKhach where Makhach = N'" +
cboMakhach.SelectedValue
+ "'";
txtDiachi.Text = Functions.GetFieldValues(str);
str="Select Dienthoai from tblKhach where Makhach= N'" +
cboMakhach.SelectedValue
+ "'";
txtDienthoai.Text = Functions.GetFieldValues(str);
}

9.3.18. Viết thủ tục cboMahang_TextChanged


private void cboMahang_TextChanged(object sender, EventArgs e)
{
string str;
if (cboMahang.Text == "")
{
txtTenhang.Text = "";
txtDongiaban.Text = "";
}
// Khi kich chon Ma hang thi ten hang va gia ban se tu dong
hien ra
str = "SELECT Tenhang FROM tblHang WHERE Mahang =N'" +
cboMahang.SelectedValue
+ "'";
txtTenhang.Text = Functions.GetFieldValues(str);
str = "SELECT Dongiaban FROM tblHang WHERE Mahang =N'" +
cboMahang.SelectedValue
+ "'";
txtDongiaban.Text = Functions.GetFieldValues(str);
}

9.3.19. Viết thủ tục txtSoluong_TextChanged


private void txtSoluong_TextChanged(object sender, EventArgs e)
{

Bài giảng Cơ sở lập trình 2 185


//Khi thay doi So luong, Giam gia thi Thanh tien tu dong cap
nhat lai gia tri
double tt, sl, dg, gg;
if (txtSoluong.Text == "")
sl = 0;
else
sl = Convert.ToDouble(txtSoluong.Text);
if (txtGiamgia.Text == "")
gg = 0;
else
gg = Convert.ToDouble(txtGiamgia.Text);
if (txtDongiaban.Text == "")
dg = 0;
else
dg = Convert.ToDouble(txtDongiaban.Text);
tt = sl * dg - sl * dg * gg / 100;
txtThanhtien.Text = tt.ToString();
}

9.3.20. Viết thủ tục txtGiamgia_TextChanged


private void txtGiamgia_TextChanged(object sender, EventArgs e)
{
//Khi thay doi So luong, Giam gia thi Thanh tien tu dong cap
nhat lai gia tri
double tt, sl, dg, gg;
if (txtSoluong.Text == "")
sl = 0;
else
sl = Convert.ToDouble(txtSoluong.Text);
if (txtGiamgia.Text == "")
gg = 0;
else
gg = Convert.ToDouble(txtGiamgia.Text);
if (txtDongiaban.Text == "")
dg = 0;
else
dg = Convert.ToDouble(txtDongiaban.Text);
tt = sl * dg - sl * dg * gg / 100;
txtThanhtien.Text = tt.ToString();
}

9.3.21. Viết thủ tục Inhoadon_Click


private void btnInhoadon_Click(object sender, EventArgs e)
{
Bài giảng Cơ sở lập trình 2 186
// Khởi động chương trình Excel
COMExcel.Application exApp = new COMExcel.Application();
COMExcel.Workbook exBook; //Trong 1 chương trình Excel có
nhiều Workbook
COMExcel.Worksheet exSheet; //Trong 1 Workbook có nhiều
Worksheet
COMExcel.Range exRange;
string sql;
int hang=0, cot=0;
DataTable tblThongtinHD, tblThongtinHang;
exBook =
exApp.Workbooks.Add(COMExcel.XlWBATemplate.xlWBATWorksheet);
exSheet = exBook.Worksheets[1];
// Định dạng chung
exRange = exSheet.Cells[1, 1];
exRange.Range["A1:B3"].Font.Size = 10;
exRange.Range["A1:B3"].Font.Name = "Times new roman";
exRange.Range["A1:B3"].Font.Bold = true;
exRange.Range["A1:B3"].Font.ColorIndex = 5; //Màu xanh da
trời
exRange.Range["A1:A1"].ColumnWidth = 7;
exRange.Range["B1:B1"].ColumnWidth = 15;
exRange.Range["A1:B1"].MergeCells = true;
exRange.Range["A1:B1"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;
exRange.Range["A1:B1"].Value = "Shop Lâm Anh";

exRange.Range["A2:B2"].MergeCells = true;
exRange.Range["A2:B2"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;
exRange.Range["A2:B2"].Value = "Cầu Giấy - Hà Nội";

exRange.Range["A3:B3"].MergeCells = true;
exRange.Range["A3:B3"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;
exRange.Range["A3:B3"].Value = "Điện thoại: (04)37562222";

exRange.Range["C2:E2"].Font.Size = 16;
exRange.Range["C2:E2"].Font.Name = "Times new roman";
exRange.Range["C2:E2"].Font.Bold = true;
exRange.Range["C2:E2"].Font.ColorIndex = 3; //Màu đỏ
exRange.Range["C2:E2"].MergeCells = true;
exRange.Range["C2:E2"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;

Bài giảng Cơ sở lập trình 2 187


exRange.Range["C2:E2"].Value = "HÓA ĐƠN BÁN";
// Biểu diễn thông tin chung của hóa đơn bán
sql = "SELECT a.MaHDBan, a.Ngayban, a.Tongtien, b.Tenkhach,
b.Diachi,
b.Dienthoai, c.Tennhanvien FROM tblHDBan AS a, tblKhach AS b, tblNhanvien
AS c WHERE
a.MaHDBan = N'" + txtMaHDBan.Text + "' AND a.Makhach = b.Makhach AND
a.Manhanvien =
c.Manhanvien";
tblThongtinHD = Functions.GetDataToTable(sql);
exRange.Range["B6:C9"].Font.Size = 12;
exRange.Range["B6:C9"].Font.Name = "Times new roman";
exRange.Range["B6:B6"].Value = "Mã hóa đơn:";
exRange.Range["C6:E6"].MergeCells = true;
exRange.Range["C6:E6"].Value = tblThongtinHD.Rows[0]
[0].ToString();
exRange.Range["B7:B7"].Value = "Khách hàng:";
exRange.Range["C7:E7"].MergeCells = true;
exRange.Range["C7:E7"].Value = tblThongtinHD.Rows[0]
[3].ToString();
exRange.Range["B8:B8"].Value = "Địa chỉ:";
exRange.Range["C8:E8"].MergeCells = true;
exRange.Range["C8:E8"].Value = tblThongtinHD.Rows[0]
[4].ToString();
exRange.Range["B9:B9"].Value = "Điện thoại:";
exRange.Range["C9:E9"].MergeCells = true;
exRange.Range["C9:E9"].Value = tblThongtinHD.Rows[0]
[5].ToString();
//Lấy thông tin các mặt hàng
sql = "SELECT b.Tenhang, a.Soluong, b.Dongiaban, a.Giamgia,
a.Thanhtien " +
"FROM tblChitietHDBan AS a , tblHang AS b WHERE
a.MaHDBan = N'" +
txtMaHDBan.Text + "' AND a.Mahang = b.Mahang";
tblThongtinHang = Functions.GetDataToTable(sql);
//Tạo dòng tiêu đề bảng
exRange.Range["A11:F11"].Font.Bold = true;
exRange.Range["A11:F11"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;
exRange.Range["C11:F11"].ColumnWidth = 12;
exRange.Range["A11:A11"].Value = "STT";
exRange.Range["B11:B11"].Value = "Tên hàng";
exRange.Range["C11:C11"].Value = "Số lượng";
exRange.Range["D11:D11"].Value = "Đơn giá";
exRange.Range["E11:E11"].Value = "Giảm giá";

Bài giảng Cơ sở lập trình 2 188


exRange.Range["F11:F11"].Value = "Thành tiền";
for (hang = 0 ; hang <= tblThongtinHang.Rows.Count - 1; hang
++)
{
//Điền số thứ tự vào cột 1 từ dòng 12
exSheet.Cells[1][hang + 12] = hang + 1;
for (cot = 0 ; cot <= tblThongtinHang.Columns.Count - 1;
cot++)
//Điền thông tin hàng từ cột thứ 2, dòng 12
exSheet.Cells[cot + 2][hang + 12]=
tblThongtinHang.Rows[hang][cot].ToString();
}
exRange = exSheet.Cells[cot][hang + 14];
exRange.Font.Bold = true;
exRange.Value2 = "Tổng tiền:";
exRange = exSheet.Cells[cot + 1][hang + 14];
exRange.Font.Bold = true;
exRange.Value2 = tblThongtinHD.Rows[0][2].ToString();
exRange = exSheet.Cells[1][hang + 15]; //Ô A1
exRange.Range["A1:F1"].MergeCells = true;
exRange.Range["A1:F1"].Font.Bold = true;
exRange.Range["A1:F1"].Font.Italic = true;
exRange.Range["A1:F1"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignRight;
exRange.Range["A1:F1"].Value = "Bằng chữ: " +
Functions.ChuyenSoSangChu
(tblThongtinHD.Rows[0][2].ToString ());
exRange = exSheet.Cells[4][hang + 17]; //Ô A1
exRange.Range["A1:C1"].MergeCells = true;
exRange.Range["A1:C1"].Font.Italic = true;
exRange.Range["A1:C1"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;
DateTime d = Convert.ToDateTime(tblThongtinHD.Rows[0][1]);
exRange.Range["A1:C1"].Value = "Hà Nội, ngày " + d.Day + "
tháng " + d.Month + "
năm " + d.Year;
exRange.Range["A2:C2"].MergeCells = true;
exRange.Range["A2:C2"].Font.Italic = true;
exRange.Range["A2:C2"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;
exRange.Range["A2:C2"].Value = "Nhân viên bán hàng";
exRange.Range["A6:C6"].MergeCells = true;
exRange.Range["A6:C6"].Font.Italic = true;
exRange.Range["A6:C6"].HorizontalAlignment =
COMExcel.XlHAlign.xlHAlignCenter;

Bài giảng Cơ sở lập trình 2 189


exRange.Range["A6:C6"].Value = tblThongtinHD.Rows[0][6];
exSheet.Name = "Hóa đơn nhập";
exApp.Visible = true;
}

Kết quả ta có tệp Excel như sau:

Hình 68. Giao diện in hoá đơn bán

9.3.22. Viết thủ tục btnTimkiem_Click


private void btnTimkiem_Click(object sender, EventArgs e)
{
if (cboMaHDBan.Text == "")
{
MessageBox.Show("Bạn phải chọn một mã hóa đơn để tìm",
"Thông báo",

Bài giảng Cơ sở lập trình 2 190


MessageBoxButtons.OK, MessageBoxIcon.Warning);
cboMaHDBan.Focus();
return;
}
txtMaHDBan.Text = cboMaHDBan.Text;
Load_ThongtinHD();
Load_DataGridViewChitiet();
btnXoaHD.Enabled = true;
btnLuu.Enabled = true;
btnInhoadon.Enabled = true;
cboMaHDBan.SelectedIndex = -1;
}

9.3.23. Viết thủ tục txtSoluong_KeyPress


private void txtSoluong_KeyPress(object sender, KeyPressEventArgs
e)
{
if(((e.KeyChar >='0') && (e.KeyChar <= '9')) ||
(Convert.ToInt32(e.KeyChar) == 8))
e.Handled = false;
else
e.Handled = true;
}

Thực hiện tương tự cho txtGiamgia_KeyPress.

9.3.24. Viết thủ tục cboMaHDBan_DropDown

Thủ tục này cập nhật lại danh sách các mã hóa đơn bán và lưu vào cboMaHDBan mỗi khi người
dùng kích chuột vào nút sổ xuống của cbo.

private void cboMaHDBan_DropDown(object sender, EventArgs e)


{
Functions.FillCombo("SELECT MaHDBan FROM tblHDBan",
cboMaHDBan, "MaHDBan",
"MaHDBan");
cboMaHDBan.SelectedIndex = -1;
}

9.3.25. Viết thủ tục frmHoadonBan_FormClosing


private void frmHoadonban_FormClosing(object sender,
FormClosingEventArgs e)
{
//Xóa dữ liệu trong các điều khiển trước khi đóng Form

Bài giảng Cơ sở lập trình 2 191


ResetValues();
}

9.3.26. Viết thủ tục btnDong_Click


private void btnDong_Click(object sender, EventArgs e)
{
this.Close();
}

10. Xây dựng Form tìm kiếm Hóa đơn bán

Mở một Form mới đặt tên là frmTimHDBan và lưu vào thư mục Forms.

Hình 69. Giao diện form Tìm kiếm hoá đơn bán

10.1. Tạo giao diện form frmTimHDBan

Điều khiển Name Text


Form frmTimHDBan TIM HOA DON BAN
TextBox txtMaHDBan, txtThang, txtNam, txtManhanvien,
txtMakhach, txtTongtien.
DataGridView DataGridView

Bài giảng Cơ sở lập trình 2 192


Button btnTimkiem, btnTimlai, btnDong

10.2. Viết mã lệnh cho form frmTimHDBan

10.2.1. Khai báo các lớp tham chiếu


using System.Data.SqlClient;
using Quanlybanhang.Class;

DataTable tblHDB;

10.2.2. Viết thủ tục FormLoad


private void frmTimHDBan_Load(object sender, EventArgs e)
{
ResetValues();
DataGridView.DataSource = null;
}

10.2.3. Viết thủ tục ResetValues


private void ResetValues()
{
foreach (Control Ctl in this.Controls)
if (Ctl is TextBox)
Ctl.Text = "";
txtMaHDBan.Focus();
}

10.2.4. Viết thủ tục btnTimkiem_Click


private void btnTimkiem_Click(object sender, EventArgs e)
{
string sql;
if ((txtMaHDBan.Text == "") && (txtThang.Text == "") &&
(txtNam.Text == "") &&
(txtManhanvien.Text == "") && (txtMakhach.Text == "") &&
(txtTongtien.Text == ""))
{
MessageBox.Show("Hãy nhập một điều kiện tìm kiếm!!!",
"Yeu cau ...",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
sql = "SELECT * FROM tblHDBan WHERE 1=1";

Bài giảng Cơ sở lập trình 2 193


if( txtMaHDBan.Text != "" )
sql = sql + " AND MaHDBan Like N'%" + txtMaHDBan.Text +
"%'";
if( txtThang.Text != "" )
sql = sql + " AND MONTH(Ngayban) =" + txtThang.Text;
if( txtNam.Text != "" )
sql = sql + " AND YEAR(Ngayban) =" + txtNam.Text;
if( txtManhanvien.Text != "" )
sql = sql + " AND Manhanvien Like N'%" +
txtManhanvien.Text + "%'";
if( txtMakhach.Text != "" )
sql = sql + " AND Makhach Like N'%" + txtMakhach.Text +
"%'";
if( txtTongtien.Text != "" )
sql = sql + " AND Tongtien <=" + txtTongtien.Text;
tblHDB = Functions.GetDataToTable(sql);
if( tblHDB.Rows.Count == 0 )
{
MessageBox.Show("Không có bản ghi thỏa mãn điều kiện!!!",
"Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
ResetValues();
}
else
MessageBox.Show("Có "+ tblHDB.Rows.Count + " bản ghi thỏa
mãn điều kiện!!!",
"Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
DataGridView.DataSource = tblHDB;
Load_DataGridView();
}

10.2.5. Viết thủ tục Load_DataGridView


private void Load_DataGridView()
{
DataGridView.Columns[0].HeaderText = "Mã HĐB";
DataGridView.Columns[1].HeaderText = "Mã nhân viên";
DataGridView.Columns[2].HeaderText = "Ngày bán";
DataGridView.Columns[3].HeaderText = "Mã khách";
DataGridView.Columns[4].HeaderText = "Tổng tiền";
DataGridView.Columns[0].Width = 150;
DataGridView.Columns[1].Width = 100;
DataGridView.Columns[2].Width = 80;
DataGridView.Columns[3].Width = 80;
DataGridView.Columns[4].Width = 80;

Bài giảng Cơ sở lập trình 2 194


DataGridView.AllowUserToAddRows = false;
DataGridView.EditMode =
DataGridViewEditMode.EditProgrammatically;
}

10.2.6. Viết thủ tục btnTimlai_Click


private void btnTimlai_Click(object sender, EventArgs e)
{
ResetValues();
DataGridView.DataSource = null;
}

10.2.7. Viết thủ tục txtTongtien_KeyPress


private void txtTongtien_KeyPress(object sender, KeyPressEventArgs
e)
{
if (((e.KeyChar >='0') && (e.KeyChar <= '9'))||
(Convert.ToInt32(e.KeyChar)== 8))
e.Handled = false;
else
e.Handled = true;
}

10.2.8. Viết thủ tục DataGridView_DoubleClick

Thủ tục này cho phép người dùng kích đúp chuột chọn một hóa đơn trên lưới, rồi gọi và hiển thị
thông tin của hóa đơn đó lên form frmHoadonBan.

Chú ý: trong form frmHoadonBan đổi thuộc tính Modifiers của điều khiển txtMaHDBan thành
Public

private void DataGridView_DoubleClick(object sender, EventArgs e)


{
string mahd;
if (MessageBox.Show("Bạn có muốn hiển thị thông tin chi
tiết?", "Xác nhận",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
mahd =
DataGridView.CurrentRow.Cells["MaHDBan"].Value.ToString();
frmHoadonban frm = new frmHoadonban();
frm.txtMaHDBan.Text = mahd;
frm.StartPosition = FormStartPosition.CenterScreen;
frm.ShowDialog();

Bài giảng Cơ sở lập trình 2 195


}
}

10.2.9. Viết thủ tục btnDong_Click


private void btnDong_Click(object sender, EventArgs e)
{
this.Close();
}

Bài giảng Cơ sở lập trình 2 196


CHƯƠNG 8.
NÂNG CẤP VÀ HOÀN THIỆN GIAO DIỆN

1. Điều khiển DataGridView và cách nhập dữ liệu trực tiếp trên lưới

Viết chương trình quản lý điểm của sinh viên, cho phép Thêm, Xem, Sửa, Xoá điểm trực tiếp trên
lưới.

Tạo một dự án mới đặt tên là QuanlyDiem.

1.1. Tạo cơ sở dữ liệu

Tạo mới cơ sở dữ liệu đặt tên là Diem.mdf gồm các bảng như sau:

Bảng btlLop

Bảng tblSinhvien

Bảng tblDiem

Giả sử bảng tblLop và tblSinhvien đã có sẵn dữ liệu như sau (để nhập dữ liệu cho các bảng tại SQL,
trong cửa sổ Server Explorer kích chuột phải tại tên bảng, chọn Show Table Data và nhập dữ liệu
cho các dòng của bảng).

Bảng tblLop

Bài giảng Cơ sở lập trình 2 197


Bảng tblSinhvien

Chú ý : Tạo kết nối tới CSDL được thực hiện tương tự như mục 2.8 của chương 7.

1.2. Xây dựng form cho chương trình

Sửa lại một số thuộc tính của Form1 và thêm các điều khiển như sau:

Điều khiển Name Text


Form frmDiem QUAN LY DIEM
Button btnNhapdiem, btnCapnhat, btnDong
ComboBox cboLop
DataGridView DataGridView

1.3. Viết mã lệnh Form frmDiem

Giả sử đã có lớp Functions trong thư mục Class.

Bài giảng Cơ sở lập trình 2 198


3/- TreeView

Là điều khiển để hiển thị hệ thống phân cấp như cấu trúc tổ chức, gia phả, hệ thống thư mục, …

Điều khiển TreeView

Các thuộc tính thường dùng của TreeView :

Nodes

Tập hợp các nút con của TreeView.

CheckBoxes

Hiển thị CheckBox cho mỗi Node hay không.

SelectedNode

Node được chọn trên TreeView (chỉ có khi viết lệnh).

HideSelection

Thuộc tính luận lý, mặc định là True, node được chọn không hiển thị màu chọn khi điều khiển
không còn focus. Nếu là False nút chọn vẫn được tô dạng chọn khi điều khiển mất focus.

Bài giảng Cơ sở lập trình 2 199


ImageList

Chỉ định điều khiển ImageList có sẵn trên form làm nguồn hình ảnh cho TreeView.

ImageIndex, ImageKey

Quy định hình ảnh mặc định nào trên ImageList hiển thị trên mỗi node của TreeView.

Indent

Quy định khoảng cách theo chiều ngang giữa mỗi cấp.

ItemHeight

Quy định chiều cao của mỗi node.

SelectedImageIndex, SelectedImageKey

Quy định hình ảnh nào trên ImageList hiển thị trên node được chọn.

Các thuộc tính của node :

Nodes

Tập hợp các nút con của mình.

Text

Nội dung đang hiển thị trên nút.

NodeFont

Font chữ hiển thị của nút.

BackColor, ForeColor

Màu nền, màu chữ của nút.

Checked

CheckBox của nút được chọn hay không.

Các thao tác trên Node :

Bài giảng Cơ sở lập trình 2 200


Thêm Node con vào tập hợp Nodes :

Hoặc

Loại bỏ Node con khỏi tập hợp Nodes :

Hoặc

Loại bỏ tất cả các Node con khỏi tập hợp Nodes :

Xác định Node tại vị trí nhấn chuột (MouseDown) :

Các sự kiện chính trên TreeView :

AfterSelect

Sự kiện xảy ra khi người dùng chọn một node.

Bài giảng Cơ sở lập trình 2 201


Bài giảng Cơ sở lập trình 2 202

You might also like