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

Giáo trình Lập trình trực quan (Nghề Quản trị mạng Trình độ Cao đẳng)

220 4 0

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

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Giáo Trình Lập Trình Trực Quan
Trường học Trường Cao đẳng
Chuyên ngành Quản trị mạng
Thể loại sách giáo trình
Định dạng
Số trang 220
Dung lượng 3,7 MB

Cấu trúc

  • BÀI 1: TỔNG QUAN VỀ C# TRONG VISUAL STUDIO 2015 (14)
    • I. TỔNG QUAN VỀ .NET FRAMEWORK (14)
      • I.1. Thành phần .NET Framework (15)
      • I.2. Những đặc điểm chính của .NET Framework (16)
    • II. GIỚI THIỆU VISUAL STUDIO 2015 (18)
      • II.1. Phiên bản Visual Studio 2015 (18)
        • II.1.1 Visual Studio Professional 2015 (18)
        • II.1.2 Visual Studio Enterprise 2015 (18)
      • II.2. Làm việc với Visual Studio 2015 (18)
    • III. CÁC LOẠI ỨNG DỤNG DÙNG C# (20)
      • III.1. Ứng dụng Windows Form (21)
      • III.2. Ứng dụng màn hình và bàn phím (21)
      • III.3. Dịch vụ hệ điều hành (21)
      • III.4. Thư viện (21)
      • III.5. Điều khiển do người sử dụng định nghĩa (21)
      • III.6. Ứng dụng báo cáo (21)
      • III.7. Ứng dụng SQL Server (22)
      • III.8. Ứng dụng PDA và Mobile (22)
      • III.9. Ứng dụng đóng gói và triển khai (22)
      • III.10. Tạo một Solution (22)
    • IV. CẤU TRÚC CHƯƠNG TRÌNH C# (22)
      • IV.1. Cấu trúc chương trình (22)
      • IV.2. Tổ chức cây Project (23)
        • IV.2.1 Nút Properties (23)
        • IV.2.2 Nút References (23)
        • IV.2.3 Nút đối tượng có giao tiếp (23)
        • IV.2.4 Nút đối tượng không có giao tiếp (23)
    • V. CẤU TRÚC THƯ MỤC CỦA CHƯƠNG TRÌNH C# 2015 (25)
  • BÀI 2: LÀM VIỆC VỚI VISUAL STUDIO 2015 (27)
    • I. CỬA SỔ SOLUTION (27)
      • I.2. Thêm Project vào Solution (27)
      • I.3. Vị trí của sổ Solution Explorer (27)
      • I.4. Tạo Foder trong Solution (27)
      • I.5. Project khởi động (27)
      • I.6. Biểu đồ lớp (27)
      • I.7. Nội dung tập tin .SLN (27)
    • II. CỬA SỔ THUỘC TÍNH CỦA PROJECT (28)
      • II.1. Ngăn Application (28)
        • II.1.1. Assembly name (28)
        • II.1.2. Output type (28)
        • II.1.3. Startup object (28)
        • II.1.4. Resouces (28)
        • II.1.5. Assembly Information (28)
      • II.2. Resources (28)
    • III. CỬA SỔ PROPERTIES (28)
    • IV. CỦA SỔ OPTION (28)
    • V. HỘP CÔNG CỤ (28)
      • V.1. Nhóm điều khiển Cômmn (28)
      • V.2. Nhóm điều khiển Containers (28)
      • V.3. Nhóm điều khiển Menus và Toolbars (28)
      • V.4. Nhóm điều khiển data (28)
      • V.5. Nhóm điều khiển Components (28)
      • V.6. Nhóm điều khiển Printing (28)
      • V.7. Nhóm điều khiển Dialog (28)
      • V.8. Nhóm điều khiển Crytal Reports (28)
    • VI. CỬA SỔ DANH SÁCH ĐỔI TƯỢNG (28)
    • VII. THỰC ĐƠN REFACTOR (28)
      • VII.1. Extrac Method (28)
      • VII.2. Encapsulate Field (28)
      • VII.3. Extract Interface (28)
      • VII.4. Reorder Parameters (28)
      • VII.5. Remove Parameters (28)
      • VII.6. Rename (28)
      • VII.7. Promote Local Variable to Parameters (28)
  • BÀI 3: CHƯƠNG TRÌNH C# 2015 (31)
    • I. BIÊN DỊCH VÀ THỰC THI CHƯƠNG TRÌNH (31)
      • I.1 Biên dịch và thực thi của C++, Visual Basic 6.0 (31)
      • I.2. Biên dịch và thực thi chương trình .NET (32)
        • I.2.1 MSIL (32)
          • 1.2.2. CLR (32)
      • I.3. Vai trò của MSIL (33)
      • I.4. Biên dịch chương trình C# (34)
        • I.4.2. Từ tiện ích CSC (37)
      • I. 5. Thực thi chương trình C# (38)
    • II. GIẢI THÍCH CÁC KHÔNG GIAN TÊN (38)
      • II.1 Không gian tên (38)
      • II.2. Một số không gian tên thường sử dụng (42)
    • III. CÁC DẠNG CỦA PHƯƠNG THỨC MAIN (42)
    • IV. ĐỊNH DẠNG KẾT QUẢ CỦA CỬA SỔ COMMAND PROMPT (43)
    • V. CHÚ THÍCH TRONG CHƯƠNG TRÌNH C# (46)
    • VI. KHAI BÁO CHỈ THỊ REGION (47)
  • BÀI 4: NỀN TẢNG CỦA C# (50)
    • I. KIỂU DỮ LIỆU TRONG C# (51)
      • I.1. Kiểu VALUE (52)
        • I.1.1 Kiểu số (52)
      • I.2. Kiểu REFERENCE (54)
      • I.3. Kiểu NULLABLE (56)
    • II. KHAI BÁO BIẾN (56)
      • II.1. Khai báo biến (57)
      • II.2. Gán giá trị cho biến (57)
      • II.3. Giá trị mặc định của biến (57)
      • II.4. Giá trị mặc định của biến kiểu Nullable (58)
      • II.5. Ký tự đặc biệt trong giá trị dạng chuỗi (58)
      • II.6. Tầm vực của biến (58)
    • III. HẰNG VÀ ENUM (58)
      • III.1. Hằng (59)
      • III.2. Kiểu liệt kê (Enum) (60)
    • IV. PHÉP TOÁN VÀ CHUYỂN ĐỔI KIỂU DỮ LIỆU (61)
      • IV.1. Phép toán (61)
      • IV.2. Chuyển đổi kiểu dữ liệu (64)
      • IV.3. BOXING VÀ UNBOXING (65)
    • V. TÊN, TỪ KHOÁ VÀ CHÚ THÍCH (66)
      • V.1. Tên (66)
      • V.2. Từ khóa (66)
      • V.3. Chú thích (66)
    • VI. CÂU LỆNH TRONG C# (66)
      • VI.1 Nhập và xuất dữ liệu (67)
      • VI.2. Cấu trúc lựa chọn (68)
      • VI.3. Cấu trúc lặp (69)
      • VI.3. Kiểm soát ngoại lệ (70)
      • VI.4. Mảng (81)
  • BÀI 5: CÁC ĐỐI TƯỢNG ĐIỀU KHIỂN CỦA C# (86)
    • I. GIỚI THIỆU (86)
    • II. CÁC THÀNH PHẦN CƠ BẢN TRÊN CỬA SỔ WINDOWS FORM (89)
      • II.1. Cửa sổ Form (89)
      • II.2. Cửa sổ thuộc tính (Properties) (90)
      • II.3. Cửa sổ Solution Explorer (90)
      • II.4. Hộp công cụ Toolbox (90)
    • III. MỘT SỐ CÔNG CỤ CƠ BẢN TRÊN HỘP TOOLBOX (91)
      • III.1. TextBox (91)
      • III.2. Label (93)
      • III.3. Các nút lệnh (93)
        • III.3.1. Button (94)
        • III.3.2. RadioButton (95)
        • III.3.3. CheckBox (96)
      • III.4. ListBox (98)
      • III.5. CheckedListBox (100)
      • III.6. ComboBox (101)
      • III.7. ScrollBar (103)
      • III.8. Trackbar (104)
      • III.9. GroupBox (105)
      • III.10. Timer (105)
      • III.11. MonthCalendar (106)
    • IV. FORM VÀ MDI FORM (107)
      • IV.1. Giới thiệu (107)
      • IV.2. Tạo MDI Form (107)
    • V. MENU (108)
    • VI. RICH TEXTBOX (110)
    • VII. FILE DIALOG (110)
      • VII.1. Điều khiển OpenFileDialog và SaveFileDialog (111)
      • VII.2. PrintDialog (112)
      • VII.3. ColorDialog (112)
      • VII.4. FontDialog (113)
  • BÀI 6: FILE VÀ REGISTRY OPERATION (122)
    • I. QUẢN LÝ TẬP TIN HỆ THỐNG (0)
      • I.1. Các lớp .NET thể hiện các File và Folder (123)
        • I.1.1. Các thuộc tính của lớp cơ bản FileSystemInfo (123)
        • I.1.2. Tạo một đối tượng DirectoryInfo (125)
      • I.2. Lớp Path (125)
    • III. ĐỌC VÀ GHI FILE (135)
      • III.1. Streams (135)
      • III.2. Làm việc với Binary Files (136)
      • III.3. Làm việc với BufferedStream (137)
      • III.4. Làm việc với những tập tin văn bản (137)
    • IV. ĐỌC VÀ GHI VÀO REGISTRY (142)
      • IV.1. Registry (142)
    • IV. 2. .NET Registry Classes (144)
  • BÀI 7: ĐỒ HOẠ VÀ MỘT SỐ XỬ LÝ NÂNG CAO (147)
    • I. GIỚI THIỆU VỀ LỚP GRAPHICS (148)
    • II. KHỞI TẠO CÁC ĐỐI TƯỢNG GRAPHIC (148)
    • III. CÁC ĐỐI TƯỢNG GRAPHIC (149)
      • III.1. Pen (150)
      • III.2. Brush (151)
      • III.3. Font (154)
      • III.4. Color (156)
      • III.5. Giới thiệu về Bitmap (158)
    • IV. CÁC CHỦ ĐỀ NÂNG CAO TRONG GDI+ (159)
      • IV.1. Antialiasing (160)
      • IV.2. Kỹ thuật Double Buffering (161)
  • BÀI 8: TRUY XUẤT DỮ LIỆU VỚI ADO.NET (163)
    • I. GIỚI THIỆU VỀ LẬP TRÌNH CƠ SỞ DỮ LIỆU (163)
      • I.1 Giới thiệu ADO.NET (163)
      • I.2. Các lớp dùng chung (164)
      • I.3. Các lớp cơ sở dữ liệu chuyên biệt (165)
    • II. ĐỐI TƯỢNG SQL (166)
      • II.2 Không gian tên Microsoft.SqlServer (166)
      • II.3 Làm việc với Microsoft.SqlServer.Management (166)
      • II.4 Thư viện SqlServer.Management (166)
      • II.5 Thao tác dữ liệu (166)
    • III. SỬ DỤNG CÁC DATABASE CONNECTION (166)
      • III.1. Sử dụng hiệu quả các Connection (167)
      • III.2. Tùy chọn một - try/catch/finally (167)
      • III.3. Tùy chọn hai - Sử dụng khối câu lệnh (168)
      • III.4. Các Transaction (giao dịch) (169)
    • IV. COMMANDS (171)
      • IV.1. Executing Commands (171)
        • IV.1.1. ExecuteNonQuery() (172)
        • IV.1.2. ExecuteReader() (172)
        • IV.1.3 ExecuteScalar() (173)
        • IV.1.4. ExecuteXmlReader() (SqlClient Provider Only) (174)
      • IV.2. Gọi các Stored Procedure (175)
        • IV.2.1. Gọi một Stored Procedure không trả lại kết quả (176)
        • IV.2.2. Gọi một Stored Procedure trả về các tham số trả về (177)
    • V. TRUY CẬP NHANH CƠ SỞ DỮ LIỆU VỚI DATA READER (178)
    • VI. MANAGING DATA VÀ RELATIONSHIPS: THE DATASET (181)
      • VI.1. Data Tables (182)
        • VI.1.1. Data Columns (183)
        • VI.1.2 Data Rows (184)
        • VI.1.3. Schema Generation (187)
        • VI.1.4. Các quan hệ dữ liệu (189)
        • VI.1.5. Ràng buộc dữ liệu (190)
    • VII. CÁC SƠ ĐỒ XML (193)
    • VIII. TẠO MỘT DATASET (199)
      • VIII.1. Tạo một DataSet dùng một DataAdapter (199)
        • VIII.1.1. Sử dụng một Stored Procedure trong một DataAdapter (200)
        • VIII.1.2. Tạo một DataSet từ XML (201)
    • IX. CÁC CỐ GẮNG THAY ĐỔI DATASET (201)
      • IX.1. Cập nhật với các Data Adapter (201)
        • IX.1.1. Chèn một dòng mới (201)
        • IX.1.2. Cập nhật một dòng đã có (202)
        • IX.1.3. Xóa một dòng (203)
      • IX.2. Viết XML xuất (203)
    • X. LÀM VIỆC VỚI ADO.NET làm việc với ADO.NET (205)
      • X.1. Phân tầng các ứng dụng (205)
      • X.2. Tạo khoá với SQL Server (206)
      • X.3. Qui tắt đặt tên (208)
      • X.4. Performance (209)
  • BÀI 9: XÂY DỰNG ỨNG DỤNG TỔNG HỢP (211)
  • TÀI LIỆU THAM KHẢO (220)

Nội dung

TỔNG QUAN VỀ C# TRONG VISUAL STUDIO 2015

TỔNG QUAN VỀ NET FRAMEWORK

Mục tiêu: Liệt kê được các thành phần chính của NET Framework; Trình bày môi trường làm việc của NET Framework;

.NET Framework là nền tảng chuẩn hóa và độc lập với ngôn ngữ lập trình, cho phép lập trình viên xây dựng, tích hợp, biên dịch và triển khai các dịch vụ web, XML, tiện ích, cũng như thực thi các chương trình đa cấu trúc trên hệ điều hành đã cài đặt NET Framework.

.NET Framework bao gồm 2 phần chính là Common Language Runtime (CLR) và NET Framework Class Library (FCL)

CLR là thành phần cốt lõi của NET Framework, chịu trách nhiệm quản lý mã thực thi, tiến trình, và tiểu trình (Threading) Nó cũng đảm bảo quản lý bộ nhớ hiệu quả, đồng thời cung cấp dịch vụ cho biên dịch, tích hợp và các tác vụ truy cập từ xa (Remoting).

 FCL bao gồm tất cả các dịch vụ như giao tiếp người sử dụng, điều khiển, truy cập dữ liệu, XML, Threading, bảo mật

Tóm lại, CLR được xem như máy ảo NET (.NET Virtual Machine), nó có thể kiểm soát, nạp và thực thi chương trình NET

FCL cung cấp các lớp, giao tiếp và giá trị đa dạng, bao gồm phương thức truy cập và các chức năng chính của hệ thống, như Microsoft.Csharp, Microsoft.Jscript, Microsoft.VisualBasic, Microsoft.Vsa, Microsoft.Win32 và không gian tên System cùng các không gian tên con của nó.

 Microsoft.Csharp: cung cấp các lớp hỗ trợ biên dịch và phát sinh mã khi sử dụng ngôn ngữ lập trình C#

 Microsoft.Jscript: cung cấp các lớp hỗ trợ biên dịch và phát sinh mã khi sử dụng ngôn ngữ lập trình J#

 Microsoft.VisualBasic: cung cấp các lớp hỗ trợ biên dịch và phát sinh mã khi sử dụng ngôn ngữ lập trình VisualBasic

 Microsoft.Vsa: cung cấp các gia tiếp cho phép tích hợp với các kịch bản của NET Framework vào ứng dụng khi biên dịch hay thực thi

 Microsoft.Win32: cung cấp hai lớp giao tiếp trực tiếp với tài nguyên của hệ điều hành và System Registry

Hệ thống bao gồm các lớp cơ sở để định nghĩa giá trị, tham chiếu, biên cố, giao tiếp, thuộc tính và kiểm soát ngoại lệ Bên cạnh đó, một số lớp khác cung cấp dịch vụ chuyển đổi kiểu dữ liệu, tham số, tính toán, xử lý và truy cập từ xa Trong đó, mã nguồn được chia thành hai loại.

Quản lý mã (Managed Code) là các chương trình được phát triển bằng những ngôn ngữ lập trình hỗ trợ NET, như C# Ví dụ, khi phát triển ứng dụng A bằng C#, chương trình sẽ được biên dịch thành tập tin thực thi (.EXE) Tập tin EXE này được gọi là Managed Code trong môi trường NET.

Unmanage Code là các chương trình được phát triển từ các ngôn ngữ lập trình không thuộc NET, chẳng hạn như Visual Basic 6.0 Khi khai báo một lớp (Class) có tên là B và biên dịch thành tập tin thư viện (.DLL), tập tin DLL này sẽ được gọi là Unmanage Code khi được tham chiếu trong môi trường NET Do đó, NET Framework có thể được xem như một môi trường tương tác với hệ điều hành dành cho các ứng dụng.

Hình 1.1: Mô tả các thành phần trong NET Framework

I.2 Những đặc điểm chính của NET Framework

The NET Framework encompasses key features such as the Common Language Runtime (CLR), the Framework Class Library (FCL), and the Common Type System, which includes common data types, metadata, and self-describing components It supports cross-language interoperability, allowing for seamless exchange and usage of components Additionally, it utilizes assemblies as distribution units, defines application domains for isolated execution, and incorporates a runtime host for executing applications.

CLR là môi trường thi hành cung cấp dịch vụ cho việc thực thi và quản lý bộ nhớ, tiểu trình của các ứng dụng hỗ trợ bởi NET Để quản lý quá trình thực thi, CLR thực hiện các bước như chọn chương trình biên dịch phù hợp với ngôn ngữ lập trình, biên dịch ứng dụng sang tập tin MSIL, và sau đó chuyển đổi mã MSIL sang mã máy thông qua trình JIT (Just-In-Time) Ngoài ra, CLR cũng tự quản lý bộ nhớ, với trình thu gom (Garbage Collector) tự động thu hồi bộ nhớ đã cấp cho tiến trình khi chương trình kết thúc, giúp tối ưu hóa hiệu suất và quản lý tài nguyên.

FCL bao gồm các thư viện lớp cơ sở, giúp bạn thực hiện các tác vụ liên quan đến giao diện, Internet, cơ sở dữ liệu và hệ điều hành một cách hiệu quả.

Common Type System (CTS) thiết lập các quy tắc cho việc khai báo, sử dụng và quản lý kiểu dữ liệu trong quá trình thi hành, đồng thời cung cấp tiêu chuẩn cho sự tương tác giữa các ngôn ngữ lập trình CTS thực hiện các chức năng chính như thiết lập khung tương tác giữa các ngôn ngữ, mã an toàn và tối ưu hóa xử lý Nó cũng cung cấp mô hình hướng đối tượng để hỗ trợ cài đặt đa ngôn ngữ trong ứng dụng, định nghĩa quy tắc mà ngôn ngữ lập trình phải tuân theo, đảm bảo tính chuyển đổi và khả năng tương tác giữa các đối tượng được tạo ra từ các ngôn ngữ khác nhau.

Metadata và Các Thành Phần Tự Mô Tả (MSDC) giải quyết vấn đề tương thích giữa các ứng dụng được viết bằng các ngôn ngữ lập trình khác nhau Trước đây, các ứng dụng thường được biên dịch thành tệp EXE hoặc DLL, gây khó khăn trong việc sử dụng chúng với các ngôn ngữ lập trình khác, như trường hợp của COM Tuy nhiên, framework NET đã cung cấp giải pháp chuyển đổi, cho phép khai báo thông tin cho mọi module và Assembly, bao gồm cả EXE và DLL.

Những thông tin này được gọi là siêu dữ liệu và sự mô tả

Cross Language Interoperability (CLI) là khả năng hỗ trợ việc trao đổi và sử dụng mã giữa các ngôn ngữ lập trình khác nhau Mặc dù CLI tạo điều kiện thuận lợi cho việc tương tác giữa các ngôn ngữ, nhưng không đảm bảo rằng mã của bạn sẽ hoạt động chính xác với các lập trình viên sử dụng ngôn ngữ khác.

Assemblies là các tập hợp kiểu dữ liệu và tài nguyên được đóng gói thành các đơn vị chức năng Chúng đóng vai trò quan trọng trong việc triển khai, quản lý phiên bản và tái sử dụng thành phần, bao gồm các tập tin EXE và DLL.

Miền ứng dụng (Application Domains) trong CLR quản lý giúp cách ly nhiều ứng dụng đang chạy trên cùng một máy tính, đảm bảo mỗi ứng dụng được nạp vào một tiến trình tách biệt mà không ảnh hưởng đến nhau Kỹ thuật mã an toàn trong Application Domains bảo đảm mã chạy độc lập với tiến trình của ứng dụng khác Khi tạm dừng một thành phần, toàn bộ tiến trình không bị dừng, cho phép loại bỏ đoạn mã đang chạy trong ứng dụng đơn Bên cạnh đó, Application Domains cho phép cấu hình, định vị, cấp quyền hoặc hạn chế quyền sử dụng tài nguyên Sự cách ly này cũng giúp CLR ngăn chặn truy cập trực tiếp giữa các đối tượng của các ứng dụng khác nhau.

 Runtime Hosts: là trung tâm thi hành cho phép nạp ứng dụng vào tiến trình,

CLR cho phép nhiều loại ứng dụng chạy trong cùng một tiến trình thông qua việc sử dụng Runtime Hosts Mỗi ứng dụng cần một đoạn mã khởi động, gọi là Runtime Hosts, để nạp kênh thực thi vào tiến trình Sau đó, Runtime Hosts tạo ra các Application Domains và thực hiện ứng dụng trong các miền ứng dụng này.

GIỚI THIỆU VISUAL STUDIO 2015

Mục tiêu: Liệt kê các phiên bản Visual Studio 2015;

Microsoft Visual Studio is a comprehensive toolkit designed for developing various types of applications, including ASP.NET web applications, XML services, desktop applications, console applications, and mobile applications.

Các ngôn ngữ lập trình phổ biến được sử dụng trong Microsoft Visual Studio để phát triển ứng dụng bao gồm Visual Basic, Visual C++, Visual C# và Visual J# Tất cả bốn ngôn ngữ này đều hoạt động trên cùng một môi trường phát triển tích hợp (IDE), cho phép người dùng chia sẻ các tiện ích và công cụ để tạo ra các giải pháp tích hợp hiệu quả.

Khi làm việc với Visual Studio 6.0, mỗi ngôn ngữ lập trình như C++, Visual Basic, J++, và Fox Pro đều có IDE riêng Đặc biệt, để phát triển ứng dụng ASP, cần sử dụng Visual Studio InterDev.

II.1 Phiên bản Visual Studio 2015

Visual Studio 2015 có 2 phiên bản chính thức là: Visual Studio Professional

Visual Studio Professional 2015 cung cấp các công cụ giao diện trực quan, cho phép người dùng dễ dàng thiết lập giao diện cho nhiều loại ứng dụng thông qua phương pháp kéo và thả (drag and drop).

Visual Studio Professional là công cụ lý tưởng cho cá nhân và nhóm lập trình nhỏ, hỗ trợ xây dựng và triển khai ứng dụng theo mô hình khách-chủ (client-server), thiết kế cơ sở dữ liệu, phát triển ứng dụng đa tầng trên nền tảng Windows, cũng như ứng dụng web và ứng dụng di động.

II.2 Làm việc với Visual Studio 2015

Kể từ khi Visual Studio NET ra đời, nó đã trở thành một IDE đa năng cho tất cả các ngôn ngữ lập trình và loại hình ứng dụng khác nhau Ứng dụng Web Forms (ASP.NET) được coi là một phần của ngôn ngữ lập trình, cho phép người dùng sử dụng chung IDE với ứng dụng Windows Forms.

Bạn có thể khởi tạo một dự án bằng ngôn ngữ lập trình Visual Basic.NET và sau đó tiếp tục mở một dự án khác bằng ngôn ngữ lập trình C# trong cùng một Solution.

Visual Studio 2015 đã có những cải tiến đáng kể so với Visual Studio.NET 2003, bao gồm nâng cấp môi trường lập trình, cải thiện định dạng mã, tối ưu hóa cơ chế gỡ lỗi, xây dựng và kiểm tra ứng dụng, cũng như nâng cao khả năng triển khai và tự động hóa, giúp hỗ trợ người sử dụng tốt hơn.

Ví dụ, trang bắt đầu của Visual Studio 2015 IDE như hình 1-2

Hình 1.2: Trang bắt đầu của Visual Studio 2015

Sau khi cài đặt thành công Visual Studio 2015, khi lần đầu tiên mở IDE, một cửa sổ sẽ xuất hiện yêu cầu bạn chọn ngôn ngữ lập trình mặc định Để chọn ngôn ngữ lập trình C#, bạn cần di chuyển đến phần Visual C# Development Setting và nhấn vào nút Start Visual Studio.

Trong các bài viết tiếp theo, chúng ta sẽ khám phá chi tiết về các công cụ, cửa sổ và cách cấu hình IDE để làm việc hiệu quả với ngôn ngữ lập trình C#.

Khi chọn ngôn ngữ lập trình C# làm ngôn ngữ mặc định, C# sẽ luôn xuất hiện đầu tiên trong danh sách các loại Project mỗi khi bạn tạo mới một Project hoặc Solution.

3, 3 ngôn ngữ lập trình còn lại là Visual basic, C++ và J# sẽ xuất hiện bên dưới phần Other Language

Hình 1.3: Màn hình yêu cầu chọn ngôn ngữ để cài đặt

Ngăn bên phải là danh sách các loại ứng dụng Windows, bao gồm các loại như: Windows Application, Console Application, Class Library, Windows Service, Crystal Reports Application,…

Trong trường hợp muốn xây dựng ứng dụng ASP.NET, bạn có thể chọn vào trong phần tạo mới, khi đó cửa sổ sẽ xuất hiện như hình 1-5

Tương tụ như trường hợp ứng dụng vWindows, ứng dụng vWebsite bao gồm các loại như: ASP.NET vWebsite, ASP.NET vWeb Service, Srystal Reports vWebsite

Trên menu Community của Visual Studio 2015, bạn sẽ tìm thấy các tùy chọn như: Hỏi câu hỏi, Kiểm tra trạng thái câu hỏi và Gửi phản hồi, giúp bạn dễ dàng tìm kiếm, gửi và theo dõi câu hỏi hoặc ý kiến về công ty Microsoft.

Trên menu này còn có các menu con, cho phép người dùng truy cập vào các địa chỉ internet chứa tài nguyên và thông tin cập nhật về Visual Studio 2015, nhằm hỗ trợ tối đa cho cộng đồng lập trình NET.

Chẳng hạn, bạn chọn vào menu có tên Developer center, cửa sổ trình duyệt xuất hiện.

CÁC LOẠI ỨNG DỤNG DÙNG C#

Mục tiêu: Liệt kê các ứng dụng của C#

Microsoft Visual C# 2015 is a programming language designed for developing applications that run on the NET Framework C# is known for its simplicity, power, type safety, and object-oriented features.

C# mang đến nhiều tính năng mới, giúp bạn phát triển ứng dụng một cách nhanh chóng, đồng thời vẫn duy trì được sự tinh tế và diễn cảm của ngôn ngữ lập trình truyền thống C.

Mặc dù tất cả các ngôn ngữ lập trình trong bộ NET đều dựa trên NET Framework, mỗi ngôn ngữ vẫn mang những đặc điểm riêng C# được coi là lựa chọn tối ưu cho việc phát triển các ứng dụng quản lý, thương mại điện tử, ứng dụng tích hợp hệ thống, thư viện, cũng như các ứng dụng dành cho máy PDA và điện thoại di động.

III.1 Ứng dụng Windows Form

When developing a desktop application with a user interface that requires the NET Framework, select Windows under Project Types and then choose Windows Application from the Templates section.

III.2 Ứng dụng màn hình và bàn phím

Nếu bạn đang phát triển một ứng dụng với giao diện người dùng là bàn phím và màn hình trên máy tính để bàn, hãy chọn loại ứng dụng là Console Application trong phần Templates Ứng dụng này cho phép người dùng tương tác thông qua màn hình Console.

Bằng cách sử dụng các không gian tên của ứng dụng Windows Forms, bạn có thể phát triển ứng dụng giao diện đồ họa ngay cả khi bắt đầu từ một ứng dụng Console Application.

III.3 Dịch vụ hệ điều hành

Trong trường hợp ứng dụng chạy thường trú trong bộ nhớ,bạn có thể chọn loại ứng dụng là vWindows Service trong phần Templates

Khi sử dụng ứng dụng này, bạn có thể tạo tập tin EXE và cài đặt chúng vào dịch vụ của hệ điều hành, cho phép bạn dễ dàng Start, Stop, Pause hoặc Continue như các dịch vụ hiện có Lưu ý rằng ứng dụng dịch vụ hệ điều hành không cần giao diện người dùng, mà thay vào đó, bạn sẽ sử dụng tiện ích Service của hệ điều hành để quản lý chúng.

Khi xây dựng thư viện dùng chung hoặc COM+ để triển khai tầng Business Logic, bạn cần chọn Class Library Sau khi hoàn tất khai báo, nếu biên dịch thành công, ứng dụng sẽ tạo ra tệp tin DLL.

Để xây dựng một thư viện bao gồm các lớp làm việc với cơ sở dữ liệu SQL Server, bạn cần tạo một Project mới loại Class Library Thư viện này sẽ được sử dụng như các Project khác, phục vụ cho mục đích cụ thể của bạn.

III.5 Điều khiển do người sử dụng định nghĩa

Ngoài các điều khiển từ các lớp của NET, người dùng có thể tạo ra điều khiển tùy chỉnh để đáp ứng các yêu cầu cụ thể Đối với ứng dụng Windows Forms, loại Project cần sử dụng là Windows Control Library, trong khi với ứng dụng ASP.NET, bạn nên chọn Project là Web Control Library.

Cả hai loại Project này đều biên dịch thành tập tin DLL, bạn có thể thêm chúng vào công cụ (Tool Box) như những điều khiển của NET

III.6 Ứng dụng báo cáo

Nếu có nhu cầu xây dựng ứng dụng báo cáo (Report) bằng Crystal Report, bạn chọn loại Project là Crystal Report Applications.Tuy nhiên, thông thường Report là

22 một phần của ứng dụng nên bạn sử dụng Crystal Report như những đối tượng của Project

III.7 Ứng dụng SQL Server Để khai báo bảng dữ liệu (Table), bảng ảo (View), thủ tục nội tại, (Store Procedure), hàm (Funtion),…bạn vào ngăn Database rồi chọn Project với loại SQL Server Project Ứng dụng này cho phép bạn thiết kế cơ sở dữ liệu SQL Server từ Visual Studio2015 thay vì từ trình SQL Server Enterprise

Lưu ý rằng, giống như trong ứng dụng Report, bạn có thể tích hợp cơ sở dữ liệu vào Project như một phần của ứng dụng, thay vì phải tạo một Project riêng biệt chỉ dành cho cơ sở dữ liệu.

III.8 Ứng dụng PDA và Mobile

Nếu bạn đang có kế hoạch phát triển ứng dụng NET cho các thiết bị di động như điện thoại thông minh hoặc máy PDA, hãy chọn Smart Device để tối ưu hóa hiệu suất và tính tương thích.

III.9 Ứng dụng đóng gói và triển khai

Sau khi hoàn tất xây dựng ứng dụng, bạn có thể tiến hành đóng gói và triển khai ứng dụng trên máy tính khác Để thực hiện việc này, hãy truy cập vào phần Other Project Types và chọn loại Project là Setup and Deployment.

Solution là một công cụ quản lý nhiều Project trong Visual Studio 2015 Khi bạn tạo Project đầu tiên, Solution sẽ tự động được tạo ra nếu chưa có Nếu Solution đã tồn tại, bạn chỉ cần chọn Solution đó để thêm Project mới vào.

Ngoài ra, bạn có thể tạo mới Solution trước khi thêm các Project khác bằng cách vào Other Project Types rồi chọn Visual Studio Solutions.

CẤU TRÚC CHƯƠNG TRÌNH C#

Mục tiêu: trình bày cấu trúc của chương trình C#

IV.1 Cấu trúc chương trình

- Cấu trúc chương trình theo Windows Application Form

//Vùng bắt đầu khai báo sử dụng không gian tên using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms;

//Vùng bắt đầu khai báo sử dụng không gian tên

//Khai báo không gian tên của ứng dụng namespace TH2

//Vùng bắt đầu khai báo tên các Class static class Program

//Vùng bắt đầu khai báo tên các phương thức trong lớp static void Main()

- Cấu trúc chương trình theo Console Command using System

//Điểm bắt đầu của ứng dụng theo kiểu C static void Main(){

} static void Main(string[] args){

System.Console.WriteLine("Hello World")

- Cấu trúc của 1 chương trình C#

IV.2 Tổ chức cây Project

IV.2.3 Nút đối tượng có giao tiếp

IV.2.4 Nút đối tượng không có giao tiếp

File1.cs File2.cs File3.cs

Class X{ } Class Y{ } Class Z{ } Class I{ } Class H{ }

CẤU TRÚC THƯ MỤC CỦA CHƯƠNG TRÌNH C# 2015

Mục tiêu: Mô tả cấu trúc các File, thư mục của một chương trình C#

- Các File của 1 chương trình C#

I Kỹ năng 1: Trình bày các ưu điểm và nhược điểm của ngôn ngữ lập trình C#

Làm việc theo nhóm, tra cứu trên Internet, các phương tiện khác và trình bày báo cáo (tối đa khoảng 2 trang)

II Kỹ năng 2: Cài đặt Visual Studio 2015

Cài đặt Visual Studio 2015 từ đĩa DVD

III Kỹ năng 3: Tìm các thông tin liên quan về C#: tính năng của phần mềm, các phiên bản

Tìm hiểu các thông tin về C# và số lượng người dùng C# hiện nay

Các tính năng vượt trội của C# so với các ngôn ngữ khác

Các phiên bản C# hiện nay đã được Microsoft công bố

Kể tên một số ứng dụng đã dùng ngôn ngữ lập trình C# mà các bạn biết

IV Kỹ năng 4: Tìm hiểu về các chương trình C# mẫu

Liệt kê và phân biệt được các thành phần trong thư mục của ứng dụng

Cách tổ chức của Cây Project, khám phá và tìm hiểu các nút

CÂU HỎI VÀ BÀI TẬP

Câu 1: Nêu các thành phần chính của NET Framework

Câu 2: Trình bày sơ đồ môi trường NET Framework

Câu 3: Liệt kê những đặc điểm chính của NET Framework

Câu 4: Liệt kê các ứng dụng dùng C#

Câu 5: Trình bày cấu trúc chương trình C#

Câu 6: Trình bày các ưu điểm và nhược điểm của ngôn ngữ lập trình C#

Làm việc theo nhóm, tra cứu trên Internet, các phương tiện khác và trình bày báo cáo (tối đa khoảng 2 trang)

Câu 7: Cài đặt Visual Studio 2015

Cài đặt Visual Studio 2015 từ đĩa DVD

Sinh viên cần nghiên cứu tài liệu học tập và thông tin liên quan để trả lời các câu hỏi Họ phải trình bày ngắn gọn và gửi lại trên giấy cho giáo viên để đánh giá kết quả kiểm tra kiến thức.

LÀM VIỆC VỚI VISUAL STUDIO 2015

CỬA SỔ SOLUTION

Mục tiêu: Phân biệt được các cửa sổ thường sử dụng trong C#

Giải pháp (Solution) được coi là một đối tượng chứa đựng các dự án (Project) trong Visual Studio 2015 Thay vì tạo từng dự án riêng lẻ, người dùng có thể sử dụng giải pháp như một Container để quản lý hiệu quả nhiều dự án cùng lúc.

Bạn có thể làm việc với nhiều dự án khác nhau, ngay cả khi chúng sử dụng các ngôn ngữ lập trình khác nhau trong cùng một IDE Khi bạn tạo một dự án mới, một Solution sẽ tự động được tạo ra để quản lý dự án đó.

I.3 Vị trí của sổ Solution Explorer

I.7 Nội dung tập tin SLN

CỬA SỔ THUỘC TÍNH CỦA PROJECT

HỘP CÔNG CỤ

V.3 Nhóm điều khiển Menus và Toolbars

V.8 Nhóm điều khiển Crytal Reports

THỰC ĐƠN REFACTOR

VII.7 Promote Local Variable to Parameters

CÂU HỎI VÀ THỰC HÀNH

Câu 1: Trình bày sự khác nhau giữa Solution và Project ?

Câu 2: Kể tên các của sổ thường dùng trong C# 2015

Câu 3: Trình bày cách thức thực thi một chương trình viết bằng ngôn ngữ lập trình C# Câu 4: Bật và tắt các của sổ trong ngôn ngữ lập trình C#

- Dùng qua các vùng tương tác trên các của sổ

Câu 5: Khám phá các thành phần trong các của sổ của ngôn ngữ lập trình C# 2015

29 o Mở cửa sổ Solution: vào View | Solution Explorer (Ctrl+W,S) hoặc dùng biểu tượng trên thanh công cụ.

 Cửa sổ thuộc tính của Project o Mở cửa sổ Properties: vào View | Properties Windows (Ctrl+W,P) hoặc dùng biểu tượng Properties trên thanh công cụ

 Cửa sổ Options o Mở cửa sổ Options: vào Tool | Options…

 Hộp công cụ (Toolbox) o Mở cửa sổ Toolbox: vào View | Toolbox hoặc (Ctrl+W,X) hoặc dùng biểu tượng Toolbox trên thanh công cụ

 Cửa sổ danh sách đối tượng

Câu 6: Xây dựng và quản lý một Solution

- Xây dựng 1 Solution đặt tên TH2

- Trong Solution TH2 có 3 Project Đặt tên PJ1, PJ2, PJ3

- Thiết lập Project 2 (PJ2) chạy đầu tiên

- Xem cách tổ chức của cây Project, khám phá và tìm hiểu các nút, các thành phần trong của các cửa sổ

CHƯƠNG TRÌNH C# 2015

BIÊN DỊCH VÀ THỰC THI CHƯƠNG TRÌNH

Mục tiêu: Trình bày trình biên dịch và cách biên dịch một chương trình trong C# I.1 Biên dịch và thực thi của C++, Visual Basic 6.0

Phiên bản Visual Studio 6.0 nổi bật với hai ngôn ngữ lập trình chính là Visual C++ và Visual Basic 6.0, mỗi ngôn ngữ đi kèm với một môi trường phát triển tích hợp (IDE), trình biên dịch (compiler) và môi trường thực thi (runtime environment) riêng biệt.

Mỗi ngôn ngữ lập trình cần một trình biên dịch để chuyển đổi mã chương trình thành tệp thực thi (Executable Code), từ đó cho phép bạn chạy chương trình trên các môi trường runtime tương ứng.

Khi triển khai chương trình viết bằng Visual Basic 6.0 trên máy tính, cần cài đặt các thư viện tương ứng để đảm bảo chương trình hoạt động Việc đính kèm các thư viện này được thực hiện trong quá trình đóng gói và triển khai chương trình.

Tóm lại, chúng ta thử hình dung cơ chế biên dịch và thực thi chương trình của hai ngôn ngữ lập trình chính trong bộ Visual Studio 6.0 như hình:

Hình 3.1: Biên dịch và thực thi chương trình

I.2 Biên dịch và thực thi chương trình NET

Trong NET, trình biên dịch của từng ngôn ngữ chuyển đổi mã nguồn thành định dạng trung gian gọi là IL (Intermediate Language) hay MSIL (Microsoft Intermediate Language), thay thế cho Executable Code trong hệ thống.

.NET không có trình Runtime riêng cho từng ngôn ngữ lập trình mà thay vào đó sử dụng một trình Runtime chung, được cung cấp bởi NET Framework, gọi là CLR (Common Language Runtime).

MSIL (Microsoft Intermediate Language) hay IL (Intermediate Language) là ngôn ngữ giúp kết nối các thành phần trong hệ thống, tương tự như mã nhị phân Nó được định nghĩa dưới dạng tập lệnh và có khả năng chuyển đổi dễ dàng sang mã máy thông qua CLR (Common Language Runtime).

Lưu ý, chương trình NET được biên dịch lần thứ nhất có thể chạy trên hệ điều hành bất kỳ hay CPU có hỗ trợ CLR

Trình CLR chịu trách nhiệm biên dịch tập tin định dạng MSIL thành mã máy Quá trình biên dịch và thực thi chương trình trên nền tảng NET được thể hiện qua hình ảnh minh họa.

Mã có thể thực thi

Mã có thể thực thi

Mã đã thực thi Runtime

Hình 3.2: Biên dịch và thực thi chương trình trong NET

CLR có vai trò thực thi mã MSIL thành mã máy thông qua cơ chế JIT (Just In Time) Do đó, quá trình biên dịch và thực thi chương trình NET được gọi là biên dịch hai lần.

Hình 3.3: Thực thi chương trình NET

Quá trình biên dịch trong NET diễn ra qua hai giai đoạn: đầu tiên, chương trình được biên dịch thành tập tin định dạng MSIL; sau đó, khi thực thi các Assembly trong môi trường NET, chúng sẽ được biên dịch thành mã máy.

Mã có thể thực thi

Mã có thể thực thi

Mã đã thực thi Runtime

Mã có thể máy thực thi

Chúng ta có thể biên dịch chương trình C# bằng Visual Studio 2015 hoặc công cụ csc.exe của NET Framework Đối với các chương trình có giao diện phức tạp, việc sử dụng Visual Studio 2015 để biên dịch là lựa chọn tối ưu nhất.

Nếu chương trình của bạn đơn giản, bạn có thể sử dụng tiện ích miễn phí csc.exe từ NET Framework thay vì bản quyền Visual Studio 2015 để biên dịch chương trình C# Để thực hiện, bạn chỉ cần chọn tên Project trong Visual Studio 2015.

R-Click | Build hoặc chọn vào trình đơn test | Run

Note that the default assembly file name is the same as the project name, and the default namespace also matches the project name You can change both the assembly file name and the namespace by selecting Project | Properties from the menu or by right-clicking the desired project in the Solution Explorer and choosing Rename.

Hình 3.4: cách thay đổi các thông tin về Project

Hình 3.5: Thay đổi tên tập tin biên dịch và không gian tên

Khi có nhiều Project trong một Solution, bạn có thể biên dịch tất cả các Project bằng cách nhấn chuột phải vào tên Solution và chọn "Build Solution" hoặc từ thực đơn "Build" chọn "Build Solution".

Nếu trước đó đã biên dịch, trong những lần biên dịch sau, thay vì chọn Build Project hay Build Solution thì có thể chọn Rebuild Project hay Rebuild Solution

Khi biên dịch chương trình C# trong Visual Studio 2015, có hai chế độ biên dịch là gỡ rối (Debug) và phát hành (Release)

Khi biên dịch dự án ở chế độ Debug, bạn sẽ nhận được hai tập tin: một tập tin định dạng MSIL tùy thuộc vào loại dự án (EXE, DLL, ) và một tập tin PDB, chứa thông tin gỡ lỗi và trạng thái của dự án.

Khi biên dịch ứng dụng tuyển sinh ở chế độ Debug, các tệp tin Exe và PDB sẽ được tạo ra và lưu trữ trong thư mục bin/Debug của ứng dụng.

Hình 3.6: tập tin Exe và Pdb

Trong trường hợp biên dịch ở chế độ Release thì tập tin Exe tạo ra nằm trong thư mục bin/Release thuộc thư mục của ứng dụng

Lưu ý, khi biên dịch chương trình C# ở chế Release thì Assembly được tạo ra đã được tối ưu hoá về mã thực thi và kích thước của tập tin

GIẢI THÍCH CÁC KHÔNG GIAN TÊN

Mục tiêu: Trình bày các không gian tên của C#

.NET Framework từ phiên bản 2.0 trở đi cung cấp nhiều không gian tên chứa các lớp (Class), giao tiếp (Interface) và kiểu dữ liệu chung cho tất cả các ngôn ngữ lập trình hỗ trợ NET.

.NET cung cấp một thư viện đồ sộ gọi là FCL (Framework Class Library), trong đó Console chỉ là một trong hàng ngàn lớp Mỗi lớp trong FCL đều có tên riêng, dẫn đến việc người lập trình khó có thể nhớ hết tên của tất cả các lớp trong NET Framework Điều này có thể gây ra vấn đề, chẳng hạn như việc tạo ra lớp trùng tên với lớp đã có.

Namespace là công cụ giúp tổ chức mối quan hệ giữa các lớp và kiểu dữ liệu trong NET, ngăn chặn xung đột tên giữa các lớp, biến và hàm Bằng cách sử dụng namespace, NET đảm bảo rằng các tên không bị trùng lặp, tạo ra một môi trường lập trình rõ ràng và hiệu quả hơn.

Trong quá trình phát triển ứng dụng, việc xây dựng một lớp từ điển có tên là Dictionary có thể gây ra xung đột biên dịch trong C#, vì ngôn ngữ này chỉ cho phép một tên duy nhất Để giải quyết vấn đề này, chúng ta cần đổi tên lớp Dictionary thành một cái tên khác, chẳng hạn như myDictionary Tuy nhiên, điều này có thể làm cho quá trình phát triển ứng dụng trở nên phức tạp và cồng kềnh, và khi đạt đến một mức độ phát triển nhất định, nó có thể trở thành cơn ác mộng cho các nhà phát triển.

Giải pháp cho vấn đề này là tạo ra một namespace, giúp giới hạn phạm vi của tên và đảm bảo rằng tên này chỉ có ý nghĩa trong khu vực đã định nghĩa.

Khi nói về một kỹ sư như Tùng, cần xác định lĩnh vực cụ thể mà anh ta chuyên môn, chẳng hạn như kỹ sư cầu đường, cơ khí hay phần mềm Điều này giúp phân biệt rõ ràng giữa các loại kỹ sư, ví dụ như lập trình viên C# sẽ phân loại Tùng là CauDuong.KySu, khác với CoKhi.KySu hay PhanMem.KySu Namespace trong trường hợp này, như CauDuong, CoKhi và PhanMem, giúp giới hạn phạm vi của các thuật ngữ, tạo ra một không gian tên rõ ràng và có ý nghĩa cho các chuyên ngành khác nhau.

Để tránh xung đột tên lớp, chúng ta có thể tạo ra các namespace khác nhau, giống như cách NET Framework xây dựng lớp Dictionary trong namespace System.Collections Điều này cho phép chúng ta tạo lớp Dictionary riêng trong namespace ProgramCSharp.DataStructures mà không gây ra tranh chấp tên.

Trong ví dụ minh họa đối tượng Console bị hạn chế bởi namespace bằng việc sử dụng mã lệnh:

Trong ví dụ này, dấu ‘.’ được sử dụng để truy cập phương thức hoặc dữ liệu trong một lớp, cụ thể là phương thức WriteLine() Cách truy cập này được thực hiện theo hướng từ trên xuống, bắt đầu từ namespace System, tiếp theo là lớp Console, và cuối cùng là các phương thức hoặc thuộc tính của lớp.

In many cases, a namespace can be divided into sub-namespaces, known as subnamespaces For example, the System namespace contains several subnamespaces, including Configuration, Collections, and Data, among others Additionally, the Collections namespace is further divided into multiple sub-namespaces.

Namespace giúp tổ chức và phân tách các kiểu trong lập trình Khi xây dựng một chương trình C# phức tạp, việc tạo ra một kiến trúc namespace riêng là cần thiết để quản lý mã nguồn hiệu quả.

Namespace cho phép quản lý kiến trúc đối tượng phức tạp một cách hiệu quả bằng cách chia nhỏ và tổ chức chúng, đồng thời không giới hạn chiều sâu của cây phân cấp.

Từ khóa "using" trong C# giúp chương trình trở nên gọn gàng hơn bằng cách cho phép lập trình viên không cần phải khai báo từng namespace cho từng đối tượng Khi sử dụng từ khóa này, bạn chỉ cần thêm dòng lệnh "using System;" ở đầu chương trình Sau đó, khi sử dụng đối tượng Console, bạn chỉ cần viết "Console." thay vì phải ghi đầy đủ "System.Console."

Ví dụ: Dùng khóa using using System; class ChaoMung

//Xuat ra man hinh chuoi thong bao Console.WriteLine(“Chao Mung”);

Lưu ý rằng cần phải sử dụng câu "using System" trước khi định nghĩa lớp ChaoMung Mặc dù chúng ta đã chỉ định sử dụng namespace System, nhưng khác với các ngôn ngữ khác, chúng ta không thể chỉ định sử dụng đối tượng System.Console.

Ví dụ 2.4: Không hợp lệ trong C# using System.Console; class ChaoMung

//Xuat ra man hinh chuoi thong bao WriteLine(“Chao Mung”);

} } Đoạn chương trình trên khi biên dịch sẽ được thông báo một lỗi như sau:

Error CS0103 The name 'WriteLine' does not exist in the current context

Biểu diễn namespace có thể giảm thao tác gõ bàn phím, nhưng có thể gây xáo trộn nếu các namespace không khác nhau Giải pháp hiệu quả là sử dụng từ khóa using cho các namespace được xây dựng sẵn và do chúng ta tạo ra, vì chúng ta đã nắm chắc thông tin về chúng Tuy nhiên, đối với namespace của bên thứ ba, không nên sử dụng từ khóa using.

Tùy thuộc vào loại ứng dụng, lập trình viên cần tham chiếu đến các không gian tên chứa các lớp và đối tượng cần thiết Bài viết này sẽ khám phá một số không gian tên phổ biến khi phát triển ứng dụng bằng C#.

CÁC DẠNG CỦA PHƯƠNG THỨC MAIN

Mục tiêu: Trình bày các dạng của phương thức Main

Phương thức Main là điểm khởi đầu quan trọng trong mỗi chương trình C#, được sử dụng khi chương trình đó là một ứng dụng thực thi.

Trong ứng dụng C# loại chương trình thực thi, cần có một và chỉ một phương thức Main trong dự án, đồng thời không nên sử dụng từ khóa Public.

Phương thức Main dạng ứng dụng Console using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace th111 { class Program { static void Main(string[] args) {

//các câu lệnh được đưa vào

Phương thức Main dạng Windows Application using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace WindowsFormsApplication1 { static class Program

/// The main entry point for the application

Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1());

Phương thức main có truyền tham số class ChaoMung { static void Main(string[] args) {

// Xuất ra màn hình chuổi thông báo truyền vào cho hàm Main System.Console.WriteLine(args.Length) ;

Phương thức Main không có truyền tham số class ChaoMung { static void Main() {

// Xuat ra man hinh chuoi thong bao

//'Chao mung ban den voi C# 2015 ' System.Console.WriteLine("Chao mung ban den voi C# 2015") ; System.Console.ReadLine() ;

ĐỊNH DẠNG KẾT QUẢ CỦA CỬA SỔ COMMAND PROMPT

Mục tiêu: sử dụng các câu lệnh để định dạng các kết quả theo yêu cầu

Nếu đã chạy ứng dụng Console Application, kết quả trình bày trên cửa sổ Command Prompt theo định dạng do người lập trình định nghĩa

To display the values of three variables in the Command Prompt, use curly braces { } along with an index number (i) to specify which variable's value to output The method can be defined as static void Standard().

Hình 3.10: Kết quả chương trình

Một số dạng thức khi thực hiện khi in ra trong của sổ Command Prompt

Bảng 3.1: Các ký tự và ý nghĩa

Ví dụ: về định dạng ngày, giờ static void Date()

Console.WriteLine("DateTime Format"); Console.WriteLine(

"(d) Short date: {0:d}\n" + "(D) Long date: {0:D}\n" + "(t) Short time: {0:t}\n" +

"(T) Long time: {0:T}\n" + "(f) Full date/short time: {0:f}\n" + "(F) Full date/long time: {0:F}\n" + "(g) General date/short time: {0:g}\n" + "(G) General date/long time: {0:G}\n" + " (default): {0} "+

Ví dụ: về định dạng số static void Number()

Console.WriteLine("Numeric Format"); Console.WriteLine(

Ví dụ: về định dạng màu sắc enum Color { Yellow = 1, Blue, Green }; static void Enumeration()

CHÚ THÍCH TRONG CHƯƠNG TRÌNH C#

Mục tiêu: sử dụng chú thích trong C# để làm các chú thích trong chương trình

Chú thích trong C# là các đoạn văn bản giúp làm rõ mục đích và chi tiết kỹ thuật của mã nguồn, hỗ trợ lập trình viên hiểu rõ hơn về câu lệnh, đoạn chương trình, phương thức, thuộc tính và lớp.

Nếu không có chú thích rõ ràng về mục đích và chi tiết kỹ thuật của đoạn chương trình, lập trình viên sẽ mất nhiều thời gian để hiểu lại mã nguồn khi phát sinh lỗi hoặc cần thay đổi, thêm chức năng Do đó, việc sử dụng Comment là rất quan trọng; chúng giúp ghi lại thông tin về các câu lệnh, đoạn chương trình, phương thức, thuộc tính hay class, đặc biệt là khi làm việc trong nhóm lập trình.

Chú thích không được đọc bởi trình biên dịch, nó không liên quan gì đến chương trình

Có 2 cách viết chú thích trong C#:

Nếu chú thích trên một dòng bạn đặt phần chú thích sau 2 dấu sổ chéo

// chú thích Nếu chú thích trên nhiều dòng bạn đặt phần chú thích trong cặp /* */ cụ thể

KHAI BÁO CHỈ THỊ REGION

Mục tiêu: sử dụng chỉ thị REGION để lập trình

Khi có nhiều phương thức muốn nhóm theo từng nhóm, có thể sử dụng khai báo mở #region và khai báo đóng là #endregion namespace myRegion

/// The main entry point for the application

#region Format of Number static void Standard()

} enum Color { Yellow = 1, Blue, Green }; static void Enumeration()

CÂU HỎI VÀ BÀI TẬP

I Kỹ năng 1: Xây dựng và thực thi một ứng dụng

1.1 Sử dụng Micosoft Visual Studio 2015 để tạo chương trình

Bước 1: Khởi động Visual Studio 2015

Start | All Programs | Microsoft Visual Studio

Bước 2: Vào menu File | New | Project

* Mặc định: Visual Studio 2015 sẽ tạo ra tập tin Program.cs chứa một namespace tên ChaoMung và trong namespace này chứa một class tên Program

Bước 4: trong phương thức Main, gõ đoạn mã lệnh sau

// Xuat ra man hinh chuoi thong bao 'Chao mung ban den voi C# 2015 ' System.Console.WriteLine("Chao mung ban den voi C# 2015") ; System.Console.ReadLine() ;

Bước 5: Để chạy chương trình, nhấn F5 hoặc nhắp vào nút

Chú ý : Khi tạo một chương trình trong C#, chúng ta nên thực hiện theo các bước sau:

Bước 1: Xác định mục tiêu của chương trình

Bước 2: Xác định những phương pháp giải quyết vấn đề

Bước 3: Tạo một chương trình để giải quyết vấn đề

Bước 4: Thực thi chương trình để xem kết quả

II Kỹ năng 2: viết các chương trình hiển thị trong cửa sổ Command Promt

Viết các chương trình hiển thị thông tin trong cửa sổ Command Prompt, bao gồm định dạng ngày giờ, tháng năm và màu sắc của ký tự hiển thị theo các ví dụ đã cho.

III Kỹ năng 3: viết chương trình theo định dạng cho sẵn ở cửa sổ Command Promt

HƯỚNG DẪN TRẢ LỜI: vận dụng các câu lệnh đã học để thực hiện các chương trình trong C#

NỀN TẢNG CỦA C#

KIỂU DỮ LIỆU TRONG C#

Mục tiêu: Phân biệt được các kiểu dữ liệu, trình bày phạm vi, các phép toán trên các kiểu dữ liệu

C# là một ngôn ngữ lập trình mạnh mẽ với hệ thống kiểu dữ liệu rõ ràng, yêu cầu khai báo kiểu cho mỗi đối tượng khi tạo, bao gồm kiểu số nguyên, số thực, chuỗi và kiểu điều khiển Kiểu dữ liệu không chỉ giúp trình biên dịch xác định kích thước của đối tượng (ví dụ, kiểu int có kích thước 4 byte) mà còn xác định các khả năng của nó, như đối tượng Button có thể vẽ và phản ứng khi được nhấn.

C# có hai loại dữ liệu chính: kiểu xây dựng sẵn và kiểu do người dùng định nghĩa Các kiểu dữ liệu này được phân thành hai nhóm: kiểu dữ liệu giá trị và kiểu dữ liệu tham chiếu Sự phân biệt này xuất phát từ cơ chế lưu trữ của chúng trong bộ nhớ, ảnh hưởng đến cách thức quản lý và sử dụng dữ liệu trong lập trình.

Trong lập trình, kiểu dữ liệu giá trị như int hay float lưu trữ giá trị thực của nó trong bộ nhớ stack, trong khi kiểu dữ liệu tham chiếu như mảng hay đối tượng lại lưu trữ địa chỉ của chúng trong bộ nhớ heap.

Khi làm việc với các đối tượng có kích thước lớn, việc lưu trữ chúng trên bộ nhớ heap mang lại nhiều lợi ích Chương 4 sẽ phân tích các ưu điểm và nhược điểm của việc sử dụng kiểu dữ liệu tham chiếu, trong khi chương này chỉ tập trung vào các kiểu dữ liệu cơ bản và kiểu xây dựng sẵn.

Tất cả các kiểu dữ liệu xây dựng sẵn, ngoại trừ đối tượng và chuỗi, đều là kiểu dữ liệu giá trị Trong khi đó, tất cả các kiểu dữ liệu do người dùng định nghĩa, ngoại trừ kiểu cấu trúc, đều thuộc về kiểu dữ liệu tham chiếu.

C# là một ngôn ngữ lập trình có cấu trúc trong bộ Visual Studio NET 2015, yêu cầu người dùng khai báo kiểu dữ liệu cho mọi biến và đối tượng trước khi sử dụng.

Trong C#, kiểu dữ liệu được chia thành hai loại chính: kiểu giá trị (Value Types) và kiểu tham chiếu (Reference Types) Kiểu giá trị, như int và char, được sử dụng để lưu trữ giá trị, trong khi kiểu tham chiếu lưu trữ tham chiếu đến giá trị thực Ngoài các kiểu dữ liệu được cài sẵn, người dùng cũng có thể định nghĩa kiểu dữ liệu riêng.

Trong phần này chúng ta tập trung tìm hiểu cách khai báo biến, các kiểu dữ liệu, hằng và enum được sử dụng trong C#

Kiểu dữ liệu Value chia thành hai loại chính: Structs, Enumerations Trong đó, Structs bao gồm kiểu số (Numeric) tương ứng với ba loại chính:

Số nguyên tổng quát (Integral)

Kiểu số thập phân (Decimal)

 Kiểu do người dùng định nghĩa (User defined)

I.1.1.1 Kiểu số nguyên tổng quát

Kiểu số nguyên tổng quát được phân loại thành nhiều loại khác nhau dựa trên kích thước và khoảng giá trị của chúng, như được trình bày trong bảng 4-1.

Kiểu Khoảng giá trị Kích thước

Sbyte byte char short ushort int uint long ulong

Số nguyên có dấu 8-bit

Số nguyên không dấu 8-bit

Số nguyên có dấu 16-bit

Số nguyên không dấu 16-bit

Số nguyên có dấu 32-bit

Số nguyên không dấu 32-bit

Số nguyên có dấu 64-bit

Số nguyên không dấu 64-bit

Bảng 4-1: Kiểu số nguyên tổng quát

Lưu ý, nếu giá trị có kiểu số nguyên vượt quá số ulong thì lỗi sẽ phát sinh khi biên dịch

Các kiểu dữ liệu số nguyên trình bày trong bảng 4-1 thuộc các không gian tên tương ứng trong NET Framework như bảng 4-2

Kiểu trong C# NET Framework byte System.byte sbyte System.sbyte char System.char int System.int32 uint System.uint32 long System.int64

Ulong System.uint64 short System.int16 ushort System.uint16

Kiểu số chấm động bao gồm hai loại chính là float và double với kích thước vào khoảng giá trị xấp xỉ trình bày trong bảng 4-3

Kiểu Giá trị xấp xỉ Số lẻ

Bảng 4-3: Kiểu số chấm động

Tương tự như kiểu dữ liệu số nguyên, kiểu số chấm động trình bày trong bảng 4-3 thuộc các không gian tên tương ứng trong NET Framework như bảng 4-4

Bảng 4-4: Kiểu số chấm động

Kiểu số thập phân 128-bit cung cấp nhiều số lẻ hơn so với kiểu số chấm động, mặc dù khoảng giá trị của nó nhỏ hơn Do đó, kiểu dữ liệu này thường được sử dụng để biểu diễn các con số liên quan đến tài chính và tiền tệ.

Khoảng giá trị xấp xỉ và số lẻ của kiểu số thập phân trình bày trong bảng 4-5

Kiểu Giá trị xấp xỉ Số lẻ decimal 1.0 x 10e-28 -> 7.9 x 10e28 28->29 số có dấu

Bảng 4-5: Kiểu số thập phân

Không gian tên tương ứng của kiểu số thập phân trong NET Framework như bảng 4-6

Kiểu trong C# NET Framework decimal System.Decimal

Bảng 4-6: Kiểu số thập phân

Kiểu luận lý dùng để khai báo biến có thể lưu trữ giá trị là true và false, không gian tên tương ứng trong NET Framework là System.Boolean

I 1.3 Kiểu do người sử dụng định nghĩa

Kiểu struct là một kiểu dữ liệu giá trị, cho phép nhóm các biến có liên quan để lưu trữ nhiều giá trị của một thực thể cụ thể.

Lưu ý, struct có thể chứa đựng constructors, hằng, thuộc tính, phương thức, chỉ mục, phép toán, biến cố và cho phépbanj khai báo các kiểu lồng

Struct có thể cài đặt interface nhưng không thể kế thừa từ struct khác, vì vậy khi khai báo struct, từ khóa protected không thể được sử dụng để chỉ định phạm vi của struct.

In C#, the Reference type is used to store references to actual values, encompassing class, interface, delegate, object, and string types This section will focus on the two remaining types: object and string.

Trong NET Framework, kiểu object tương ứng với System.object Tất cả các kiểu dữ liệu trong C#, bao gồm cả kiểu do người dùng định nghĩa, đều kế thừa trực tiếp hoặc gián tiếp từ object, cho dù đó là kiểu reference hay value.

Bạn có thể gán giá trị cho một biến kiểu object, và quá trình biến đổi từ kiểu value sang kiểu object được gọi là boxing Ngược lại, khi một biến kiểu object chuyển đổi về kiểu value, quá trình này được gọi là unboxing.

Kiểu string trình bày một chuỗi ký tự dạng Unicode Không gian tên tương ứng trong NET Framework là System.String

Mặc dù kiểu dữ liệu string là kiểu tham chiếu, nhưng các phép toán so sánh bằng (= =) và không bằng (!=) lại so sánh giá trị của đối tượng string, không phải tham chiếu.

Khai báo chuỗi hằng: string = ;

Ví dụ: string HoTen = "Ho Viet Ha" ;

Khai báo biến kiểu chuỗi: string [= "Noi dung chuoi hang"] ;

Ví dụ: string hoten = "Nguyen Van Teo" ;

= System.Console.ReadLine() ;

Ví dụ: hoten = System.Console.ReadLine() ;

Ví dụ: System.Console.WriteLine("Do dai cua chuoi la:") ;

Một số thao tác trên chuỗi:

Length Chiều dài của chuỗi

ToLower() Trả về bản sao của chuỗi ở kiểu chữ thường

ToUpper() Trả về bản sao của chuỗi ở kiểu chữ IN HOA

Bảng 4-7: Một số thao tác trên chuỗi

Ví dụ: Nhập vào họ và tên, in ra màn hình họ tên bằng chữ IN HOA, chữ thường, độ dài của họ và tên using System ; class HoTen

{ static void Main() { // Khai bao bien string hoten ; // Nhap gia tri cho bien chuoi Console.Write("Nhap Ho va Ten: ") ;

56 hoten = Console.ReadLine() ; // Thao tac tren chuoi string HT = hoten.ToUpper() ; string ht = hoten.ToLower() ; int dodai = hoten.Length ; // Xuat ra man hinh

Console.WriteLine("Ho va Ten (chu IN HOA): {0}", HT) ; Console.WriteLine("Ho va Ten (chu thuong): {0}", ht) ; Console.WriteLine("Do dai Ho va Ten la: {0}",dodai) ; }

Bảng 4-8: Các kiểu ký tự đặc biệt

Kiểu Nullable là đối tượng thuộc cấu trúc System.Nullable có thể trình bày khoảng giá trị dạng Value và có thể thêm giá trị null

Chẳng hạn, Nullable, đánh vần là “ Nullable of int32 ”, có thể gán giá trị bất kỳ từ -2147483648 đến 2147483647 hay giá trị đó có thể là null

KHAI BÁO BIẾN

Mục tiêu: Khai báo được biến và đối tượng có kiểu dữ liệu trước khi sử dụng

- Biến là một vùng lưu trữ ứng với một kiểu dữ liệu

- Biến có thể được gán giá trị và cũng có thể thay đổi giá trị trong khi thực hiện các lệnh của chương trình

Khai báo biến với kiểu dữ liệu trong C# là điều cần thiết trước khi sử dụng biến trong chương trình Để thực hiện việc khai báo biến, bạn cần tuân theo cú pháp nhất định.

{Kiểu dữ liệu} tên biến [= giá trị khởi tạo];

II.2 Gán giá trị cho biến

Nếu trước đó bạn không gán giá trị khởi tạo, trong quá trình tính toán bạn có thể sử dụng các phép toán để gán giá trị cho chúng

Ví dụ : Khởi tạo và gán giá trị một biến class Bien

// Khai bao va khoi tao bien int bien = 9 ;

System.Console.WriteLine("Sau khi khoi tao: bien = {0}", bien) ; // Gan gia tri cho bien bien = 5 ; // Xuat ra man hinh System.Console.WriteLine("Sau khi gan: bien = {0}", bien) ; }

II.3 Giá trị mặc định của biến

Khi một biến được khai báo nhưng chưa có giá trị, việc truy cập vào biến đó trong quá trình biên dịch sẽ gây ra lỗi Ví dụ, nếu bạn khai báo một biến k có kiểu int và sau đó cố gắng sử dụng phương thức Writeline của đối tượng Console để in giá trị của biến này, lỗi sẽ xảy ra trong dòng lệnh tiếp theo.

Ví dụ : Khởi tạo và gán giá trị một biến class Bien

// Khai bao va khoi tao bien int k ;

System.Console.WriteLine("Sau khi khoi tao: bien = {0}", bien) ;

II.4 Giá trị mặc định của biến kiểu Nullable

Khi làm việc với kiểu dữ liệu Nullable, bạn có thể khai báo biến bằng cách sử dụng ký tự dấu hỏi (?) Để gán giá trị cho biến kiểu Nullable, bạn áp dụng cú pháp giống như khi gán giá trị cho biến kiểu value.

II.5 Ký tự đặc biệt trong giá trị dạng chuỗi

Khi làm việc với biến có kiểu string, bạn có thể sử dụng ký tự @ để chỉ định các ký tự đặc biệt trong chuỗi

II.6 Tầm vực của biến

Tầm vực của biến phụ thuộc vào từ khóa được chỉ định trước tên biến, bao gồm public, protected, internal và private Nếu không khai báo từ khóa trước biến nằm ngoài phương thức, biến đó sẽ mặc định là private.

Lưu ý, các từ khóa public, protected, internal, private có thể sử dụng các phương thức hay hằng, enum

Nếu biến khai báo có từ khóa là public thì không giới hạn quyền truy cập từ bên ngoài đến chúng

Nếu sử dụng từ khóa protected trước biến thì giới hạn quyền truy cập trong class và những Class kế thừa từ Class chứa đựng biến đó

Trong Assembly hiện tại, để truy cập vào biến có phạm vi internal, lớp (Class) sử dụng biến đó phải thuộc cùng một Assembly với lớp chứa biến.

Từ khóa "private" trong lập trình được sử dụng để ấn định biến, cho phép truy cập chỉ bên trong lớp (Class) mà nó được khai báo Nếu một biến trong lớp không được ấn định với bất kỳ từ khóa nào như public, private, protected hay internal, thì mặc định nó sẽ được coi là private.

Biến cục bộ là biến có tầm vực ngay bên trong phương thức mà nó được khai báo

The keyword "static" is utilized for classes, methods, constructors, properties, events, and variables This article explores the application of the static keyword specifically in the context of variable declaration, providing a detailed understanding of its usage in programming.

HẰNG VÀ ENUM

Mục tiêu: trình bày khái niệm và cách khai báo của hằng

- Hằng cũng là một biến nhưng giá trị của hằng không thay đổi trong khi thực hiện các lệnh của chương trình

- Hằng được phân làm 3 loại:

+ Giá trị hằng (literal) + Biểu tượng hằng (symbolic constants) + Kiểu liệt kê (enumerations)

= ;

Từ khóa `const` được sử dụng để khai báo một trường hoặc biến cục bộ với giá trị đã được chỉ định và không thể thay đổi trong suốt quá trình thực thi.

Thông thường khai báo hằng khi giá trị nào đó không thay đổi

Ví dụ: x = 100; // 100 được gọi là giá trị hằng

Ví dụ: Nhập vào bán kính, in ra chu vi và diện tích hình tròn class HinhTron

// Khai bao bieu tuong hang const double PI = 3.14159 ; // Khai bao bien int bankinh ; double chuvi , dientich ; string chuoi ;

// Nhap gia tri cho bien chuoi System.Console.Write("Nhap ban kinh hinh tron: ") ; chuoi = System.Console.ReadLine() ;

Chuyển đổi chuỗi thành số và gán vào biến số bankinh bằng cách sử dụng System.Convert.ToInt32(chuoi) Tính giá trị cho biến chuvi bằng công thức chuvi = 2 * bankinh * PI và diện tích bằng diện tích = bankinh * bankinh * PI Cuối cùng, xuất kết quả ra màn hình.

System.Console.WriteLine("Chu vi hinh tron = {0:0.00}", chuvi) ; System.Console.WriteLine("Dien tich hinh tron = {0:0.00}", dientich) ; }

III.2 Kiểu liệt kê (Enum)

Kiểu liệt kê, hay còn gọi là danh sách liệt kê, là tập hợp các tên hằng có giá trị không thay đổi và được định nghĩa bằng từ khóa enum Từ khóa này được sử dụng để tạo ra một bảng dạng liệt kê (enumeration) chứa các hằng có kiểu dữ liệu khác nhau, thường được gọi là enumerator list.

Mỗi phần tử trong enumeration đều có kiểu dữ liệu riêng, cho phép gán giá trị bất kỳ là kiểu số tổng quát (integral), ngoại trừ kiểu char Nếu không khai báo kiểu cho phần tử trong enumeration, kiểu dữ liệu mặc định sẽ là int.

Nếu không khai báo giá trị thì giá trị mặc định của phần tử thứ nhất là 0 các phần tử kế tiếp giá trị tăng lên 1

Ví dụ : Sử dụng kiểu liệt kê

// Khai báo kiểu liệt kê enum NhietDoNuoc

{DoDong=0, DoNguoi , DoAm@, DoNong`, DoSoi0} static void Main()

Console.WriteLine(“Nhiet do dong:

Console.WriteLine(“Nhiet do nguoi:{0}”,

Console.WriteLine(“Nhiet do am: {0}”,

Console.WriteLine(“Nhiet do nong: {0}”,

Console.WriteLine(“Nhiet do soi: {0}”,

Chúng ta đã tìm hiểu về các kiểu dữ liệu, cách khai báo biến, tầm vực của biến và khai báo hằng, enum trong chương trình C#

Trong phần kế tiếp, chúng ta tiếp tục tìm hiểu các phép toán sử dụng trong C# và các phương thức chuyển đổi kiểu dữ liệu.

PHÉP TOÁN VÀ CHUYỂN ĐỔI KIỂU DỮ LIỆU

Mục tiêu: Trình bày cách chuyển đổi dữ liệu, và thực thi các phép toán, chuyển đổi các kểi dữ liệu trong C#

Chúng ta đã tìm hiểu các kiểu dữ liệu, cách khai báo biến, hằng, enum trong phần trước

Trong phần này chúng ta tập trung tìm hiểu các phép toán sử dụng trong chương trình C# và cách khai chuyển đổi kiểu dữ liệu

Các vấn đề chính sẽ được đề cập:

 Chuyển đổi kiểu dữ liệu

Nhóm toán tử Toán tử Ý nghĩa

Toán học + - * / % cộng , trừ, nhân chia, lấy phần dư Logic & | ^ ! ~ && || true false phép toán logic và thao tác trên bit

Ghép chuỗi + ghép nối 2 chuỗi

Tăng, giảm ++, tăng / giảm toán hạng lên / xuống 1 Đứng trước hoặc sau toán hạng

Dịch bit > dịch trái, dịch phải

Quan hệ == != < > = bằng, khác, nhỏ/lớn hơn, nhỏ/lớn hơn hoặc bằng

Chỉ số [] cách truy xuất phần tử của mảng Ép kiểu ()

Bảng 4-9: Các nhóm toán tử trong C#

C# cung cấp một loạt các phép toán với các ký tự đặc biệt, cho phép thực hiện các biểu thức tính toán đa dạng Các phép toán trong C# được phân loại thành nhiều nhóm như phép toán số học, phép toán logic, phép toán gán, và phép toán so sánh Một số ký hiệu phổ biến bao gồm: ==, !=, , =, cùng với các phép toán nhị phân như +, -, ^, &, ~, cũng như các phép toán tăng giảm như ++, và sizeof().

Ngoài ra, một số phép toán có thể cài đặt chồng (overloading)

IV.1.1 Phép toán Arithmetic (số học)

Phép toán số học bao gồm 5 phép toán chính: + , - , * , / , %

C# cung cấp các phép toán logic ứng với các ký hiệu tượng trưng như: &, l, ^,

!, ~, ||, true, false Thường các phép toán này được sử dụng trong các phát biểu điều khiển

! : phép phủ định, && : phép và, || : phép hoặc

IV.1.3 Phép toán tăng giảm

Phép toán tăng và giảm cho phép bạn tăng hoặc giảm giá trị hiện tại đi giá trị là

Các phép toán tăng giảm : += , -= , *= , /= , % IV.1.4 Phép toán quan hệ

Phép toán quan hệ (Relational) bao gồm các phép toán như: == (bằng) , ! (khác) , , = thường sử dụng trong phát biểu điều khiển

Phép toán gán (Assignment) trong C# bao gồm: =, +=, -=, *=, /=, %=, &=, l=,

^=, ; =; is nhỏ hơn, lớn hơn, nhỏ hơn hay bằng, lớn hơn hay bằng và là

Logic trên bit AND & Và trên bit

OR | hoặc trên bit Điều kiện AND && Và trên biểu thức điều kiện Điều kiện OR || Hoặc trên biểu thức điều kiện Điều kiện ?: điều kiện tương tự if

=>>; &= ;^= ; | Bảng 4-11: Thứ tự ưu tiên của các nhóm toán tử (chiều ưu tiên từ trên xuống)

IV.2 Chuyển đổi kiểu dữ liệu

Chuyển đổi kiểu dữ liệu là một thao tác phổ biến trong các ứng dụng C#, cho phép bạn thực hiện chuyển đổi giữa các kiểu số trong giới hạn cho phép Một ví dụ điển hình là chuyển đổi kiểu trong giới hạn cho phép giữa các kiểu dữ liệu, được gọi là Chuyển đổi Ngầm (Implicit Conversion).

Một đối tượng có thể chuyển đổi kiểu dữ liệu theo hai hình thức: ngầm định và tường minh Hình thức ngầm định thực hiện chuyển đổi tự động, trong khi hình thức tường minh yêu cầu sự can thiệp trực tiếp từ lập trình viên, tương tự như trong C++ và Java Ví dụ, trong C++, khi khai báo `short x = 5;` và `int y;`, việc gán `y = x;` thực hiện chuyển kiểu ngầm định, nhưng khi gán `x = y;` sẽ gây lỗi biên dịch Để thực hiện chuyển đổi hợp lệ, lập trình viên cần sử dụng cú pháp `x = (short) y;`.

Bạn có thể tham khảo giới hạn cho phép chuyển đổi kiểu dữ liệu trong bảng 5-2

Từ kiểu dữ liệu Sang kiểu dữ liệu

Short, int, long, float, double, decimal Short, ushort, int, uint, long, ulong, float, double, decimal

Int, long, float, double, decimal Int, uint, long, ulong, float, double, decimal Long, float, double, decimal

Long, ulong, float, double, decimal Float, double, decimal

Ushort, int, uint, long, ulong, float, double, decimal Double

Bảng 4-12: Chuyển đổi kiểu dữ liệu

Bạn có thể thực hiện chuyển đổi kiểu dữ liệu tương thích thông qua phương pháp Chuyển đổi Rõ Ràng (Explicit Conversion) Nếu kiểu dữ liệu không phù hợp, sẽ xảy ra lỗi Bảng 5-3 cung cấp danh sách các kiểu dữ liệu có khả năng chuyển đổi.

Từ kiểu dữ liệu Sang kiểu dữ liệu

Short ushort int uint long ulong char float double decimal

Byte, ushort, uint, ulong, char Sbyte or char

Sbyte, byte, ushort, uint, ulong, char Sbyte, byte, short, char

Sbyte, byte, short, ushort, uint, ulong, char Sbyte, byte, short, ushort, int, char

Sbyte, byte, short, ushort, uint, int, ulong, char Sbyte, byte, short, ushort, uint, int, long, char Sbyte, byte, short

In programming, data types are essential for defining the nature of data and how it can be manipulated Common data types include signed and unsigned integers such as sbyte, byte, short, ushort, int, uint, long, and ulong, which cater to various ranges of numerical values Additionally, character data is represented by the char type, while floating-point numbers are handled by float and double types For precise decimal representation, the decimal type is utilized Understanding these data types is crucial for effective coding and data management.

Bảng 4-13: Chuyển đổi kiểu dữ liệu

Khi chuyển đổi kiểu dữ liệu, cần lưu ý rằng có thể xảy ra mất mát thông tin do làm tròn số hoặc tự cắt bỏ để phù hợp với kiểu dữ liệu mới Để thực hiện việc chuyển đổi này, bạn có thể áp dụng một số phương thức của đối tượng Convert.

Khái niệm Boxing và Unboxing cho phép kiểu giá trị được xử lý như một đối tượng Boxing là quá trình chuyển đổi kiểu giá trị thành đối tượng kiểu tham chiếu, giúp lưu trữ giá trị trên vùng nhớ heap Ngược lại, Unboxing là quá trình trích xuất dữ liệu từ đối tượng kiểu tham chiếu trở lại kiểu giá trị.

Trong bài viết này, chúng ta đã khám phá các phép toán cơ bản trong ngôn ngữ lập trình C# và cách thực hiện chuyển đổi kiểu dữ liệu thông qua các phương thức của đối tượng Convert, cũng như sử dụng phương thức ToString của đối tượng đó.

TÊN, TỪ KHOÁ VÀ CHÚ THÍCH

Mục tiêu: trình bày cách khai báo biến, tên các đối tượng và cách sử dụng các chú thích

Tên là một khái niệm quan trọng trong lập trình, giúp xác định các đại lượng khác nhau như tên hằng, tên biến, tên mảng, tên hàm, tên phương thức và tên đối tượng.

Tên phải bắt đầu bằng một chữ cái hoặc dấu gạch dưới, và các ký tự tiếp theo có thể là chữ cái, chữ số hoặc dấu gạch dưới.

Ghi chú: Không được đặt tên trùng với từ khóa của C#

Keywords in C# are predefined terms that serve specific functions in the programming language Some essential C# keywords include abstract, default, foreach, object, sizeof, unsafe, as, delegate, goto, and operator Additional keywords encompass stackalloc, ushort, base, do, if, out, static, using, bool, double, implicit, override, string, and virtual Other important keywords are break, else, in, params, struct, volatile, byte, enum, int, private, switch, and void Moreover, case, event, interface, protected, this, while, catch, explicit, internal, public, throw, char, extern, is, readonly, true, checked, false, lock, ref, try, class, finally, long, return, typeof, const, fixed, namespace, sbyte, uint, continue, float, new, sealed, ulong, decimal, for, null, short, and unchecked also play crucial roles in C#.

Bảng 4-14: Từ khóa của ngôn ngữ C#d

- Lời giải thích trên một dòng: Đặt sau cặp kí hiệu //

- Lời giải thích trên nhiều dòng: Đặt lồng giữa cặp kí hiệu /* và */

CÂU LỆNH TRONG C#

Mục tiêu: Mô tả cú pháp và vận dụng các câu lệnh trong C# để lập trình để thực hiện các bài toán

Trong C#, một chỉ dẫn lập trình hoàn chỉnh được gọi là câu lệnh Chương trình bao gồm nhiều câu lệnh được sắp xếp tuần tự Mỗi câu lệnh cần phải kết thúc bằng một dấu chấm.

67 phẩy, ví dụ như: int x; // một câu lệnh x = 32; // câu lệnh khác int y =x; // đây cũng là một câu lệnh

Trình biên dịch sẽ xử lý các câu lệnh theo thứ tự từ đầu đến cuối trong danh sách Bắt đầu từ vị trí đầu tiên, nó lần lượt thực hiện từng câu lệnh cho đến lệnh cuối cùng.

Có hai loại câu lệnh:

+ Câu lệnh đơn giản: lệnh khai báo, lệnh gán, lệnh gọi hàm

+ Câu lệnh có cấu trúc: câu lệnh điều kiện, lệnh lặp, các lệnh đơn giản đặt trong cặp dấu {…}

VI.1 Nhập và xuất dữ liệu

System.Console.Writeline(“{0} {1} … {n}”, bt_0, bt_1, …, bt_n);

Trong đó: bt_0 truyền giá trị cho {0} bt_1 truyền giá trị cho {1}

… bt_n truyền giá trị cho {n}

VI.1.2 Nhập dữ liệu Để nhập liệu cho các biến khác kiểu string, ta sử dụng cú pháp:

= .Parse(System.Console.ReadLine()); Để nhập liệu cho các biến kiểu string, ta sử dụng cú pháp003A

= System.Console.ReadLine();

Ví dụ 2.5 Nhập xuất dữ liệu using Sysstem; class Vd25

{ static void Main(string[] args)

Console.Clear(); string ten; int tuoi; float dtb;

Console.Write("Nhap ten: "); ten = Console.ReadLine();

68 tuoi = int.Parse(Console.ReadLine());

Console.Write("Nhap dtb: "); dtb = float.Parse(Console.ReadLine());

Console.WriteLine(" -"); Console.WriteLine("Du lieu sau khi nhap: ");

Tuoi:{1},DTB:{2:00.0}",ten,tuoi,dtb);

VI.2 Cấu trúc lựa chọn

VI.2.1 Cấu trúc if else …

Cú pháp: if ()

; hoặc if ()

- là biểu thức cho giá trị true hoặc false

- là một lệnh đơn giản hoặc có thể là một lệnh có cấu trúc

- Nếu cho giá trị true thì hay sẽ được thực thi, ngược lại sẽ thực thi

- Một điểm khác biệt với C++ là biểu thức trong câu lệnh if phải là biểu thức logic, không thể là biểu thức số

- Ta có thể sử dụng cấu trúc if lồng nhau

Cú pháp: switch ()

Trong cấu trúc switch, biểu thức lựa chọn sẽ được so sánh với các biểu thức hằng để xác định khối lệnh cần thực hiện Lệnh break là cần thiết để thoát khỏi cấu trúc switch.

VI.3.1 Cấu trúc lặp while

Cú pháp: while ()

Mô tả quá trình thực hiện trong cấu trúc lặp while:

Nếu vẫn còn đúng thì sẽ được thực hiện, ngược lại sẽ thoát khỏi vòng lặp

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

while ()

Mô tả quá trình thực hiện trong cấu trúc lặp do … while:

Trong cấu trúc lặp do … while, sẽ được thực hiện trước, sau đó

được kiểm tra, nếu đúng lại được thực hiện, ngược lại sẽ thoát khỏi vòng lặp

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

Cú pháp: for ([]; []; [])

- là biểu thức khởi tạo biến điều khiển

- là biểu thức logic

- là biểu thức thay đổi biến điều khiển

Mô tả quá trình thực hiện trong cấu trúc lặp for

Bước 1: được thực hiện

Bước 2: được thực hiện Nếu có giá trị đúng thì qua Bước 3, ngược lại qua Bước 5

Bước 3: được thực hiện

Bước 4: được thực hiện

VI.3.4 Cấu trúc lặp foreach

Cú pháp: foreach ( in )

Trong đó: chứa các phần tử cùng kiểu dữ liệu với

Mô tả quá trình thực hiện trong cấu trúc lặp for

Các phần tử trong sẽ được lần lượt gán cho , và sau mỗi lần gán, sẽ được thực thi Quá trình này sẽ kết thúc khi tất cả các phần tử trong tập hợp đã được xử lý.

đã được duyệt

VI.3 Kiểm soát ngoại lệ

Ngôn ngữ C# cho phép xử lý lỗi và điều kiện không bình thường thông qua các ngoại lệ, là những đối tượng chứa thông tin về sự cố của chương trình Cần phân biệt rõ giữa bug, lỗi và ngoại lệ: bug là lỗi lập trình có thể sửa chữa trước khi mã nguồn được phát hành, trong khi ngoại lệ không được bảo vệ và khác biệt với bug Mặc dù bug có thể gây ra ngoại lệ, việc xử lý bug nên được ưu tiên hơn là dựa vào ngoại lệ.

Lỗi do hành động của người sử dụng thường xảy ra khi họ nhập sai dữ liệu, chẳng hạn như nhập ký tự chữ cái thay vì số Mặc dù lỗi này có thể gây ra ngoại lệ, nhưng chúng ta có thể ngăn chặn điều này bằng cách xử lý lỗi với mã hợp lệ Những lỗi này có thể được dự đoán và phòng ngừa hiệu quả.

Dù chúng ta có loại bỏ tất cả các lỗi và dự đoán mọi sai sót của người dùng, vẫn có thể xảy ra những vấn đề không lường trước như tình trạng thiếu bộ nhớ hoặc thiếu tài nguyên hệ thống do ảnh hưởng từ các chương trình khác Mặc dù không thể ngăn chặn hoàn toàn các ngoại lệ này, chúng ta có thể xử lý chúng một cách hiệu quả để bảo vệ chương trình khỏi những tác động tiêu cực.

Khi một chương trình gặp phải tình huống ngoại lệ, chẳng hạn như thiếu bộ nhớ, nó sẽ tạo ra một ngoại lệ và việc thực thi của các chức năng hiện tại sẽ bị tạm dừng cho đến khi có phương pháp xử lý ngoại lệ phù hợp Nếu chức năng đang hoạt động không xử lý được ngoại lệ, nó sẽ bị chấm dứt và hàm gọi sẽ nhận được thông báo về việc xử lý ngoại lệ Nếu hàm gọi cũng không thực hiện xử lý ngoại lệ, ngoại lệ sẽ được CLR xử lý sớm, dẫn đến việc chương trình kết thúc.

Một trình xử lý ngoại lệ là một khối lệnh trong chương trình nhằm xử lý các ngoại lệ phát sinh Việc xử lý ngoại lệ được thực hiện thông qua câu lệnh cụ thể.

Khi sử dụng cấu trúc try-catch, lý tưởng nhất là nếu một ngoại lệ xảy ra, chương trình có thể xử lý và khắc phục vấn đề, tiếp tục hoạt động bình thường Ngay cả khi chương trình không thể tiếp tục, việc bắt và xử lý ngoại lệ cho phép chúng ta in ra thông điệp ý nghĩa và kết thúc chương trình một cách rõ ràng.

Khi một đoạn chương trình cần thực hiện mà không cần quan tâm đến các ngoại lệ, chẳng hạn như việc giải phóng tài nguyên đã được cấp phát, ta có thể đặt mã này trong khối finally Điều này đảm bảo rằng đoạn mã sẽ luôn được thực hiện, ngay cả khi có ngoại lệ xảy ra.

VI.3.1 Phát sinh và bắt giữ ngoại lệ

Trong ngôn ngữ C#, chúng ta có thể tạo ra các đối tượng kiểu dữ liệu để xử lý ngoại lệ, cụ thể là System.Exception và các đối tượng dẫn xuất từ kiểu này Namespace System của CLR cung cấp nhiều kiểu dữ liệu xử lý ngoại lệ mà người dùng có thể áp dụng trong chương trình, bao gồm ArgumentNullException, InvalidCastException, OverflowException, cùng với nhiều lớp khác.

Trong C#, để thông báo về một sự kiện bất thường trong một lớp, bạn cần phát sinh một ngoại lệ bằng cách sử dụng từ khóa throw Ví dụ, bạn có thể tạo ra một thể hiện mới của ngoại lệ và ném nó với câu lệnh: throw new System.Exception();

Khi ngoại lệ xảy ra, chương trình sẽ dừng lại và CLR sẽ tìm kiếm trình xử lý ngoại lệ Nếu không tìm thấy trong phương thức hiện tại, CLR sẽ tiếp tục tìm kiếm trong các phương thức gọi cho đến khi tìm thấy Nếu không có trình xử lý nào được phát hiện khi trở về lớp Main(), chương trình sẽ kết thúc.

Ví dụ 3.1 phát sinh ngoại lệ

- using System; namespace Programing_CSharp

Console.WriteLine("Enter Func2 "); throw new System.Exception();

Unhandled Exception: System.Exception: Exception of type

An exception of type 'System.Exception' was encountered during the execution of the program The error originated in the Func2() method at line 23 of the exception01.cs file This issue was propagated from the Func1() method, which is located at line 17 of the same file, and ultimately affected the Main() method at line 10.

CÁC ĐỐI TƯỢNG ĐIỀU KHIỂN CỦA C#

GIỚI THIỆU

Mục tiêu: Mô tả được các thành phần chính của giao diện Visual C#.net

Bộ Visual Studio Net bao gồm nhiều ngôn ngữ lập trình như C#, C++.Net và Visual Basic.Net Ngoài ra, nó còn là một môi trường phát triển tích hợp (IDE) với nhiều cửa sổ thiết kế và công cụ, cùng với hệ thống trợ giúp tích hợp để hỗ trợ người dùng trong quá trình phát triển phần mềm.

Trong chương này, chúng ta sẽ tập trung nghiên cứu Visual Studio C# với trọng tâm là các dự án triển khai trên Windows, đặc biệt là Windows Forms Application Để tạo một dự án mới trên Windows Forms Application, bạn cần thực hiện theo các bước hướng dẫn cụ thể.

Bước 1 Vào Start menu  Visual Studio 2015

Xuất hiện cửa sổ Start Page – Microsoft Visual Studio như hình 5.1

Hình 5.1 Cửa sổ Start Page – Visual Studio

The Recent Projects box displays your recently worked-on projects, allowing you to easily click to open existing projects To access a specific project, simply click on Project… under the Open section of the Recent Projects box If you wish to create a new project, click on Project… under the Create section within the same box.

Bước 2 Tại cửa sổ của hình 5.1, vào menu File  New  Project (hoặc bấm tổ hợp phím nóng Ctrl_Shift_N)

Xuất hiện cửa sổ New Project như hình 5.2

Hình 5.2 Cửa sổ New Project

Trong hộp Templates của hình 5.2 có nhiều khuôn dạng được cài đặt sẵn trong Visual Studio

- Windows Forms Application: Tạo ứng dụng với giao diện sử dụng Windows

- Class Library: Dự án tạo các lớp sử dụng cho các ứng dụng khác

A WPF Application (Windows Presentation Foundation Application) is a project designed to create applications with a Windows interface This type of project is similar to a Windows Forms Application but was introduced in Visual Studio 2015 with the NET Framework 3.0 WPF offers many powerful features that encompass those of Windows Forms, making it the optimal choice for modern application development compared to Windows Forms Applications.

- WPF Browser Application: Dự án tạo ứng dụng với giao diện sử dụng trình duyệt web

- Console Application: Dự án tạo ứng dụng trên các dòng lệnh chạy trên nền DOS

- Empty Project: Dự án rỗng tạo ứng dụng cục bộ

- Windows Service: Dự án tạo các dịch vụ cho Windows

- WPF Custom Control Library: Dự án tạo thư viện liên kết động phục vụ cho WPF

- WPF User Control Library: Dự án tạo thư viện liên kết động phục vụ cho WPF

- Windows Forms Control Library: Dự án tạo thư viện liên kết động phục vụ cho Windows Forms Application

Trong mục Template, ta chọn Windows Forms Application

- Trong hộp Project types chọn Visual C#  Windows

- Trong hộp Templates chọn Windows Forms Application

- Textbox nhãn Name gõ: Nhập tên dự án

- Textbox nhãn Location chọn ổ đĩa cần lưu trữ, xuất hiện màn hình như hình 5.3

Hình 5.3 Cửa sổ lập trình Window Form

CÁC THÀNH PHẦN CƠ BẢN TRÊN CỬA SỔ WINDOWS FORM

Cửa sổ Form mặc định có tên là Form1 và đang ở chế độ thiết kế Để chuyển sang cửa sổ mã lệnh, người dùng cần vào cửa sổ Solution Explorer, chọn Form1.cs và sau đó chọn View Code.

Hình 5.4 Cửa sổ Solution Explorer

Trên Form ta có thể thêm vào các điều khiển khác nhau (các điều khiển này nằm trên hộp công cụ Toolbox

II.2 Cửa sổ thuộc tính (Properties)

Cửa sổ thuộc tính, nằm bên trái cửa sổ Form trong hình 5.3, có thể được kích hoạt nếu không hiển thị bằng cách vào menu View và chọn Properties Window, hoặc sử dụng tổ hợp phím Ctrl+W, P.

Bằng cách sử dụng thanh trượt, người dùng có thể khám phá nhiều thuộc tính khác nhau trên cửa sổ thuộc tính Những thuộc tính này cho phép cấu hình cửa sổ Form hoặc các điều khiển, với điều kiện rằng Form hoặc nút điều khiển tương ứng đã được chọn.

Các thuộc tính thường dùng cho Form gồm: Name, BackColor, Enable, Font, Size, Text, WindowState

Hình 5.5 Cửa sổ thuộc tính

II.3 Cửa sổ Solution Explorer

Cửa sổ Solution Explorer trong Visual Microsoft Net hiển thị cây giải pháp hiện hành, cho phép người dùng duyệt qua tất cả các dự án và các file liên quan Khi nhấp đúp vào một file dự án, file đó sẽ mở ra để chỉnh sửa Để hiển thị cửa sổ Solution Explorer, người dùng có thể vào menu View và chọn Solution Explorer, hoặc sử dụng tổ hợp phím Ctrl+W, S.

II.4 Hộp công cụ Toolbox

Hộp công cụ Toolbox là nơi chứa nhiều điều khiển có thể thêm vào Form Để hiển thị Toolbox, người dùng có thể vào menu View và chọn mục Toolbox hoặc sử dụng tổ hợp phím Ctrl+W, X Hộp Toolbox sắp xếp các điều khiển theo từng loại nhóm.

- Common Controls: Các điều khiển cơ bản

- Containers: Các điều khiển liên quan khung chứa

- Menus & Toolbars: Các điều khiển tạo thực đơn, thanh công cụ

- Data: Các điều khiển liên quan về dữ liệu, khung chứa dữ liệu

MỘT SỐ CÔNG CỤ CƠ BẢN TRÊN HỘP TOOLBOX

Mục tiêu: sử dụng một số công cụ cơ bản trên hộp Toolbox để thiết kế giao diện phục vụ cho các bài toán ứng dụng

Trên Windows Form, có nhiều loại điều khiển khác nhau được sử dụng để phát triển ứng dụng, bao gồm cả điều khiển đơn giản và phức tạp Tất cả các điều khiển này chia sẻ một tập thuộc tính để thiết lập cách thức hoạt động và cách trình bày Bên cạnh các thuộc tính, mỗi điều khiển còn có các sự kiện (event) để xác định phản ứng của nó trước các tác động bên ngoài.

Tất cả các điều khiển trên Windows Form đều được kế thừa từ lớp Control, lớp này chứa các thành phần cần thiết để xây dựng giao diện người dùng, bao gồm cả lớp Form Lớp Control cũng định nghĩa các phương thức cơ bản liên quan đến thuộc tính, sự kiện và phương thức của các điều khiển Cuối cùng, Control là một lớp trừu tượng, do đó không thể tạo trực tiếp một thể hiện của nó.

Để nhập văn bản trong một ứng dụng, chúng ta sử dụng điều khiển TextBox Để thêm TextBox vào Form, chỉ cần nhấp đúp vào biểu tượng TextBox trong hộp ToolBox hoặc kéo thả biểu tượng này lên Form.

Sau khi thêm hoặc chọn TextBox trên Form, cửa sổ thuộc tính sẽ hiển thị tất cả các thuộc tính của TextBox, bao gồm các giá trị của thuộc tính của điều khiển được chọn Các thuộc tính thường dùng của TextBox bao gồm:

Name Tên của TextBox thường bắt đầu bởi tiếp đầu ngữ txt

BackColor Chọn màu cho TextBox

Enabled Khóa cứng hoặc không một TextBox

Font Định dạng Font chữ cho chuỗi dữ liệu của TextBox

Multiline Cho phép nhập dữ liệu vào TextBox trên nhiều dòng

PasswordChar Kí tự đại diện khi nhập mật khẩu

Text Chuỗi dữ liệu xuất hiện trong TextBox

Visible Hiển thị hoặc che dấu TextBox

Bảng 5.1 Bảng thuộc tính của điều khiển TextBox

Các sự kiện (Event) thường gặp: Leave, TextChanged, Enter

Ví dụ 5.1 Thiết lập các thuộc tính và sử dụng sự kiện TextChanged

Để tạo một TextBox với tên là txtA, bạn cần thiết lập thuộc tính Text là trống và sự kiện TextChanged để hiển thị thông báo về chuỗi dữ liệu của txtA Đoạn mã xử lý sự kiện này sẽ được viết trong Form1.cs với cú pháp: public Form1().

} private void txtA_TextChanged(object sender, EventArgs e)

MessageBox.Show("Vua bam: " + txtA.Text);

Ví dụ 5.2 Thiết lập các thuộc tính và sử dụng sự kiện Leave

TextBox đầu tiên có tên là txtA, với màu nền hồng và không có nội dung Khi sự kiện Leave xảy ra, màu sắc của txtA sẽ chuyển sang trắng, con trỏ sẽ chuyển sang txtB, dữ liệu trong txtB sẽ được xóa hoàn toàn, và cuối cùng, màu sắc của txtB sẽ chuyển sang hồng.

- TextBox thứ nhất với Name: txtA, BackColor: màu trắng, Text: trống Đoạn mã lệnh xử lý sự kiện trong Form1.cs có dạng: public Form1()

} private void txtA_Leave(object sender, EventArgs e)

{ txtA.BackColor = Color.FromArgb(((int)(((byte)(255)))),

93 txtB.Focus(); txtB.Clear(); txtB.BackColor = Color.FromArgb(((int)(((byte)(255)))),

Ví dụ 5.3 Tạo TextBox tự động và sử dụng sự kiện Leave

Tạo 5 TextBox với tên lần lượt là txt0, txt1, txt2, txt3, txt4, mỗi TextBox có kích thước 200x40 Thiết lập sự kiện Leave cho từng TextBox để hiển thị thông báo: “Bạn vừa rời khỏi TextBox txt?” Đoạn mã lệnh trong Form1.cs sẽ có dạng: public Form1().

TextBox[] A; A = new TextBox[5]; for (int i = 0; i < 5; i++)

A[i].Leave += new System.EventHandler(this.textBox_Leave);

} private void textBox_Leave(object sender, EventArgs e)

MessageBox.Show("Ban vua roi khoi TextBox " + a.Name);

Label thường được sử dụng để làm nhãn diễn tả và được đặt trên Form Các thuộc tính thường dùng của Label là: Name, BackColor, Font, ForeColor, và Text

Có 3 loại nút lệnh: Button, RadioButton, CheckBox Mỗi nút lệnh được sử dụng để biểu diễn kiểu nút lệnh chuẩn của Windows Cả 3 loại nút lệnh này được thừa kế từ lớp cơ sở: ButtonBase Hẳn là những ai lần đầu lập trình trên Windows cũng đều ngạc nhiên khi RadioButton và CheckBox lại thuộc vào nhóm các nút lệnh, bởi do hai loại nút này giống Button ở điểm: Chúng có thể được kích hoạt, và chúng đều có nhãn

Button là nút nhấn trên Windows, tích hợp các thuộc tính, phương thức và sự kiện để đơn giản hóa thao tác Để thêm Button vào Form, chỉ cần nhấp đúp vào biểu tượng Button trong hộp ToolBox hoặc kéo thả biểu tượng Button từ hộp ToolBox lên Form.

Sau khi thêm nút vào biểu mẫu hoặc khi nhấn chọn nút trên biểu mẫu, cửa sổ thuộc tính sẽ hiển thị tất cả các thuộc tính của nút Các thuộc tính thường được sử dụng của nút bao gồm:

Name Tên của Button thường bắt đầu bởi tiếp đầu ngữ btn

BackColor Chọn màu cho Button

Enabled Khóa cứng hoặc không một Button

Font Định dạng Font chữ cho chuỗi dữ liệu của Button

ForeColor Màu sắc cho chuỗi Text

Text Chuỗi dữ liệu xuất hiện trong Button

Visible Hiển thị hoặc che dấu Button

Bảng 5.2 Bảng thuộc tính của Button

Các sự kiện (Event) thường gặp: Click

Ví dụ 5.4 Tạo Label, TextBox, Button và sử dụng sự kiện Click

Hãy tạo 1 Label (Text: Input Name), 1 TextBox (thuộc tính Name: txtName, Text: trống), 1 Button (Name: btnOk, Text: OK) trong hình 5.7

Yêu cầu: Khi kích vào Button OK thì xuất hiện dòng thông báo: “Bạn vừa nhập tên ” + txtName.Text

Hình 5.7 Mô tả ví dụ 5.4 Đoạn mã lệnh trong Form1.cs có dạng: public Form1()

} private void btnOK_Click(object sender, EventArgs e)

MessageBox.Show("Ban vua nhap ten " + txtName.Text); txtName.Clear(); txtName.Focus();

Ví dụ 5.5: Tạo Form có 2 nút lệnh như hình vẽ 5.8

- Khi click chuột vào button1  xuất hiện “Vừa bấm button1”

- Khi click chuột vào button2  xuất hiện “Vừa bấm button2”

Hình 5.8 Mô tả ví dụ 5.5

Hướng dẫn: Ta chỉ cài đặt chung một sự kiện Click cho cả hai Button1 và Button2 như sau: private void button_Click(object sender, EventArgs e)

MessageBox.Show("Vua bam " + a.Text);

Trong phần InitializeComponent() của Form1.Designer.cs, ta sửa thêm lần lượt

2 sự kiện vào sau phần xây dựng của Button1 và Button2 như sau:

//Button1 this.button1.Click += new System.EventHandler(this.button_Click);

//Button2 this.button2.Click += new System.EventHandler(this.button_Click);

RadioButton là công cụ dùng để tạo các nút chọn radio, thường được sử dụng khi cần chọn một trong nhiều tùy chọn Trong một nhóm RadioButton, chỉ có thể chọn một radio duy nhất, giúp người dùng dễ dàng thực hiện lựa chọn của mình.

Nút chọn radio không chỉ có các thuộc tính tương tự như các mục đã đề cập, mà còn sở hữu một thuộc tính quan trọng là thuộc tính Checked, giúp xác định xem nút radio đó có được chọn hay không.

Sự kiện thường sử dụng trong nút chọn radio là Click

Ví dụ 5.6: Tạo Form có 3 RadioButton, 1 PictureBox như hình vẽ 5.9

- Khi chọn Vang  PictureBox chuyển thành màu vàng

- Khi chọn Do  PictureBox chuyển thành màu đỏ

- Khi chọn Xanh  PictureBox chuyển thành màu xanh.

Hình 5.9 Mô tả ví dụ 5.6 Đoạn mã lệnh trong Form1.cs có dạng: public Form1()

} private void radioButton1_CheckedChanged(object sender, EventArgs e)

{ if (radioButton1.Checked) pictureBox1.BackColor = Color.Yellow;

} private void radioButton2_CheckedChanged(object sender, EventArgs e)

{ if (radioButton2.Checked) pictureBox1.BackColor = Color.Red;

} private void radioButton3_CheckedChanged(object sender, EventArgs e)

{ if (radioButton3.Checked) pictureBox1.BackColor = Color.Green;

CheckBox tương tự RadioButton nhưng chỉ khác ở điểm, ta có thể chọn nhiều CheckBox cùng lúc

Ví dụ 5.7: Tạo Form có 3 CheckBox, 1 Label (thuộc tính Text nhập “Bạn chưa chọn gì cả”) như hình vẽ 5.10

Yêu cầu: Khi chọn CheckBox nào thì dữ liệu Text tương ứng sẽ hiện ra trên Label, ngược lại sẽ hiện dòng chữ: Bạn chưa chọn gì cả!!!

Hình 5.10 Mô tả ví dụ 5.7 Đoạn mã lệnh trong Form1.cs có dạng: public Form1()

The `checkBox_CheckedChanged` method updates a label to display the selected checkboxes It initializes a string to indicate the selected options and appends the text of each checked checkbox If a checkbox is unchecked, it attempts to remove its text from the string Finally, if at least one checkbox is selected, the label shows the selected options; otherwise, it prompts the user that no options have been selected.

The code snippet defines a method called `checkBox_CheckedChanged` that updates a label based on the state of three checkboxes When a checkbox is selected, its text is appended to a string that starts with "You have selected: " If at least one checkbox is checked, the method removes the trailing comma and space, displaying the selected items in `label1` If none of the checkboxes are checked, it sets `label1` to "You haven't selected anything!!!".

Trong phần InitializeComponent() của Form1.Designer.cs, ta sửa thêm lần lượt

3 sự kiện vào sau phần xây dựng của checkBox1, checkBox2 và checkBox3 như sau: //checkBox1 this.checkBox1.CheckedChanged += new

System.EventHandler(this.checkBox_CheckedChanged);

//checkBox2 this.checkBox2.CheckedChanged += new

System.EventHandler(this.checkBox_CheckedChanged);

//checkBox3 this.checkBox3.CheckedChanged += new

System.EventHandler(this.checkBox_CheckedChanged);

ListBox là công cụ hữu ích cho việc tạo ra hộp danh mục, cho phép người dùng dễ dàng chọn lựa bằng cách nhấp chuột Trong ListBox, người dùng có thể chọn một hoặc nhiều danh mục cùng một lúc.

Ngoài các thuộc tính tương tự như các mục nêu trên, ListBox còn có một thuộc tính cần quan tâm:

- Thuộc tính Items nhằm nhập vào ListBox các mục chọn

- Thuộc tính SelectionMode, có 4 giá trị:

+ None : Không có mục nào được chọn

+ One : Chỉ chọn được một mục chon

+ MultiSimple : Có thể chọn được nhiều mục chọn

+ MultiExtended : Có thể chọn nhiều mục chọn, và người sử dụng có thể dùng phím Shift, Ctrl, mũi tên để chọn

- Thuộc tính Sorted nhằm sắp xếp các mục chọn (nếu có giá trị true)

Sự kiện mà ListBox thường dùng là SelectedIndexChanged

- Để lấy được một mục trong danh mục ta sử dụng thuộc tính SelectedItem

FORM VÀ MDI FORM

Mục tiêu: Vận dụng thiết kế Form để tạo ra các giao diện với người dùng IV.1 Giới thiệu

Trong các dự án trước đây, chúng ta đã nghiên cứu giao diện đơn tài liệu SDI (Single-Document Interface), nơi mọi Form trong ứng dụng đều ngang hàng và không có sự phân cấp Bên cạnh đó, C# cũng hỗ trợ tạo các chương trình giao diện đa tài liệu MDI (Multiple-Document Interface), trong đó có một cửa sổ cha chứa các cửa sổ con Ví dụ, Microsoft Word 97 là một chương trình MDI cho phép mở nhiều cửa sổ tài liệu con Tất cả các cửa sổ con trong MDI chia sẻ thanh công cụ và thanh thực đơn từ cửa sổ cha, và chúng luôn được giới hạn trong không gian của cửa sổ cha.

IV.2 Tạo MDI Form Để tạo một MDI Form, từ Form thông thường, ta thay đổi thuộc tính IsMdiContainer bằng true

Ví dụ 5.16: Tạo Windows Appliaction tên MDI Example Tại Form xuất hiện, đặt các thuộc tính Name: fclsMDIParent, Text: MDIParent, IsMdiContainer: true

Kết quả: Sau khi đặt thuộc tính cho Form, Form chuyển sang màu xám đen

Để tạo thêm một Form mới trong dự án, vào menu Project và chọn Add Windows Form, đặt tên là fclsChild1.cs với thuộc tính Text: Child 1 Tiếp tục thêm Form thứ ba có tên fclsChild2.cs và thuộc tính Text: Child 2 Mặc dù có thể tạo nhiều Form, nhưng chỉ có một MDI Form duy nhất Đảm bảo rằng Form cha fclsMDIParent đang hiển thị; nếu không, hãy vào Solution Explorer và nhấp đúp vào fclsMDIParent Sau đó, nhấp đúp vào Form này để kích hoạt sự kiện mặc định (Load) và nhập mã: private void fclsMDIParent_Load(object sender, EventArgs e).

{ fclsChild1 objChild = new fclsChild1(); objChild.MdiParent = this; objChild.Show();

Câu lệnh đầu tiên khai báo biến đối tượng fclsChild1 và khởi tạo nó thành thể hiện của Form fclsChild1 Câu lệnh thứ hai quan trọng vì nó thiết lập thuộc tính MdiParent của Form fclsChild1 tới Form fclsMDIParent, nhờ vào việc thiết lập thuộc tính IsMdiContainer của Form fclsMDIParent là true Sau khi lưu lại các thay đổi và nhấn F5 để chạy chương trình, kết quả hiển thị như hình 5.16.

Hình 5.16 Form con xuất hiện trong Form cha

Để trở về chương trình thiết kế ban đầu, bạn cần kích đúp chuột vào Form fclsChild1 trong cửa sổ Solution Explorer Tiếp theo, hãy thêm vào Form này một nút (Button) với thuộc tính Name là btnShowChild2 và Text là Show Child 2.

Kích đôi chuột vào Button này để kích hoạt sự kiện Click của nó, sau đó nhập vào đoạn mã sau: private void btnShowChild2_Click(object sender, EventArgs e)

{ fclsChild2 objChild = new fclsChild2(); objChild.MdiParent = this.MdiParent; objChild.Show();

Kết quả thu được như hình 5.17.

Hình 5.17 Các Form con ngang hàng với nhau

MENU

Mục tiêu: Trình bày cách tạo ra menu và cài đặt code cho các menu

Thanh thực đơn (menu) là một yếu tố quan trọng trong các phần mềm, và trong C#, điều khiển MenuStrip giúp lập trình viên dễ dàng tích hợp thanh thực đơn vào ứng dụng Hộp thoại (Dialog) cung cấp một phương pháp khác để người dùng chọn lựa các mục bằng cách đánh dấu trong hộp có sẵn hoặc chọn từ danh sách Bài viết này sẽ khám phá các thành phần như OpenFileDialog, SaveFileDialog, PrintDialog, ColorDialog, FontDialog, RichTextBox, và PrintDocument.

MenuStrip là một cấu trúc thanh thực đơn cho Form, có thể được thêm vào thông qua hộp công cụ Toolbox Mặc dù MenuStrip không hiển thị trực tiếp trên Form, nhưng nó sẽ xuất hiện ở vị trí bên dưới Một hộp với tiêu đề "Type here" sẽ xuất hiện ở góc trên bên trái của Form, hướng dẫn người dùng nhập các lựa chọn cho thực đơn.

Ví dụ 5.16: Hãy tạo thực đơn sau:

Hình 5.18 Kết quả chèn menu

In example 5.16, to create an underline character, the ampersand (&) is used before the character, such as typing &File to generate "File." To assign shortcut keys for the menu items, the properties table with the ShortCutKeys attribute is utilized For instance, the menu item "Open" has the properties Name: openMenu and ShortCutKeys: Ctrl+O, while "Save" is defined as Name: saveMenu and ShortCutKeys: Ctrl+S Additionally, "Print" is set as Name: printMenu and ShortCutKeys: Ctrl+P, "Font" as Name: fontMenu, "Foreground" as Name: foreGroundMenu, and "Background" as Name: backGroundMenu.

Trong ví dụ 5.16, ta sẽ thực hiện các sự kiện tương ứng với mỗi mục trong menu, trong đó:

- Open: Chọn một tập tin và sao chép đến RichTextBox

- Save: Chọn đường dẫn của tập tin và lưu nội dung của

RichTextBox vào vị trí đường dẫn đã chọn

- Print: Chọn lựa các thông số in và đưa thông tin máy in bận

- Font: Chọn Font cho văn bản trong RichTextBox

- Foreground: Chọn và đặt màu cận cảnh cho RichTextBox

- Background: Chọn và đặt màu nền cho RichTextBox.

RICH TEXTBOX

Mục tiêu của bài viết này là hướng dẫn cách tạo và cài đặt RichTextBox trong ứng dụng RichTextBox cho phép người dùng nhập và chỉnh sửa văn bản, đồng thời cung cấp nhiều công cụ định dạng nâng cao Để bắt đầu, hãy chọn RichTextBox từ hộp công cụ ToolBox và thêm nó vào Form, mở rộng RichTextBox gần như toàn bộ kích thước của Form Chúng ta không thêm bất kỳ điều khiển nào khác, đảm bảo không còn khoảng trống nào trên Form Các mục trong menu File và menu Format sẽ được đặt ở phía trên, bên trái của Form.

Để RichTextBox1 tự động thay đổi kích thước cùng với Form, cần thiết lập thuộc tính Anchor của RichTextBox thành Top, Bottom, Left, Right và đặt thuộc tính WordWrap thành false để tránh ngắt dòng không gọn gàng.

Thanh cuộn ngang, dọc sẽ tự động thêm vào richTextBox1 khi cần thiết Thuộc tính ScrollBar sẽ đảm trách công việc này với giá trị mặc định là Both

RichTextBox cung cấp phương thức LoadFile để tải văn bản từ tập tin và SaveFile để lưu văn bản vào tập tin Chúng ta sẽ sử dụng các phương thức này thông qua hộp thoại menu trong các phần tiếp theo Để thực hiện việc tải hoặc lưu tập tin, cần xác định tên tập tin và loại tập tin Hộp thoại sẽ giúp người dùng chọn tên tập tin, và trong ứng dụng này, chúng ta sẽ làm việc với kiểu PlainText, tức là các tập tin văn bản đơn giản không có định dạng đặc biệt.

FILE DIALOG

Mục tiêu: Trình bày cách tạo và cài đặt code cho các FileDialog

VII.1 Điều khiển OpenFileDialog và SaveFileDialog

Để thêm các điều khiển OpenFileDialog và SaveFileDialog vào Form, hãy chọn chúng từ hộp công cụ Toolbox Mặc dù openFileDialog và saveFileDialog1 không hiển thị trực tiếp trên Form, chúng sẽ xuất hiện bên cạnh menuStrip1 Các điều khiển này có phương thức ShowDialog cho phép người dùng chọn tập tin để mở hoặc lưu Ví dụ, khi người dùng chọn tập tin HelloWorld.cs để mở và nhấn nút Open, tên tập tin sẽ được lưu vào thuộc tính FileName của richTextBox1.

Hình 5.20 Chọn 1 tập tin để mở

Khi người dùng nhấp vào mục "Open" trong menu "File", một hộp thoại mở tập tin sẽ xuất hiện, cho phép tải nội dung tập tin đã chọn vào richTextBox1 Để thực hiện điều này, cần viết mã cho sự kiện của mục "Open" Trên cửa sổ thiết kế, hãy nhấp đúp vào mục "Open" trong menu "File" và nhập đoạn mã sau: private void openMenu_Click(object sender, EventArgs e).

{ openFileDialog1.ShowDialog(); richTextBox1.LoadFile(openFileDialog1.FileName,

Kết quả thu được như hình 5.21

Hình 5.21 Hiệu chỉnh văn bản

Tương tự cho mục chọn Save của menu File, ta điền vào đoạn mã sau: private void saveMenu_Click(object sender, EventArgs e)

{ saveFileDialog1.ShowDialog(); richTextBox1.SaveFile(saveFileDialog1.FileName,

VII.2 PrintDialog Điều khiển PrintDialog cho phép người sử dụng cấu hình các nhiệm vụ in ấn như chọn lựa máy in, số bảng in, số trang in Kích trên mục chọn Print của menu File để khởi tạo sự kiện Click Để thực hiện in ấn văn bản, ta cần viết mã C# trên từng dòng của văn bản, và ta sẽ nghiên cứu việc thực hiện in ấn này sau

To implement the PrintDialog in your application, select it from the ToolBox, which will display printDialog1 next to saveFileDialog1 In the Click event for the Print menu item, insert the following code: private void printMenu_Click(object sender, EventArgs e).

{ printDialog1.ShowDialog(); richTextBox1.Text = "Máy in bận\n Thử lại sau.";

ColorDialog cho phép người dùng chọn màu từ bảng màu Khi người dùng nhấp vào Foreground trong mục chọn Color của menu Format, bảng màu sẽ hiển thị (Hình 5.21) Chúng ta sẽ viết sự kiện để khi người dùng chọn một màu trên bảng màu, văn bản trong richTextBox1 sẽ được thay đổi màu sắc tương ứng.

In the design screen, add a ColorDialog control from the Toolbox to the Form, which will appear beneath the Form window Double-click on Foreground in the Color selection section of the Format menu, and then insert the following code into the Click event: private void foreGroundMenu_Click(object sender, EventArgs e).

{ colorDialog1.ShowDialog(); richTextBox1.ForeColor = colorDialog1.Color;

Thực hiện tương tự cho mục chọn BackColor

Khi người dùng nhấp vào mục "Font" trong menu, một hộp thoại Font sẽ xuất hiện, cho phép họ chọn và thay đổi phông chữ của richTextBox1 Hình 5.22 minh họa bảng Font sau khi người dùng kích chuột vào mục "Font" trong menu "Format".

In the design screen, add the FontDialog control from the Toolbox to the Form, which will appear below the Form window Double-click on the Font option in the Format menu, and then insert the following code into the Click event: private void fontMenu_Click(object sender, EventArgs e).

{ fontDialog1.ShowDialog(); richTextBox1.Font = fontDialog1.Font;

CÂU HỎI VÀ BÀI TẬP

Bài 1 Tạo Form có 1 ComboBox, 1 ListBox, 1 TextBox, 1 Label, 4 Button (thuộc tính lần lượt là Name: btnAdd, Text: &Add; Name: btnDelete, Text: &Delete, Enabled: False; Name: btnEdit, Text: &Edit, Enabled: False; Name: btnClose, Text: &Close), 1 PictureBox như hình vẽ 5.23

- Khi kích nút Add thì dữ liệu màu từ TextBox sẽ thêm vào ComboBox, ListBox

- Khi kích nút Delete thì màu được chọn từ ComboBox và ListBox sẽ bị xóa

Khi người dùng chọn màu từ bảng danh mục màu của ComboBox, màu tương ứng sẽ hiển thị trong ListBox và PictureBox sẽ được tô màu theo lựa chọn đó Ngược lại, khi màu được chọn trong bảng danh mục màu của ListBox, màu tương ứng sẽ hiển thị trong ComboBox và PictureBox cũng sẽ được tô màu theo lựa chọn từ danh mục màu.

Khi người dùng chọn màu trong ComboBox hoặc ListBox và nhấn nút Edit, dữ liệu đã chọn sẽ được chuyển vào TextBox để chỉnh sửa Để bổ sung dữ liệu vào ComboBox hoặc ListBox, người dùng chỉ cần nhấn nút Add.

Hình 5.24 Minh họa bài tập 1

Bài 2 Tạo Form có 2 Label, 2 TextBox, 1 MonthCalendar như hình vẽ 5.24

- Khi kích chọn lần 1 để chọn ngày trên MonthCalendar, ngày được chọn sẽ hiện thị trong TextBox1 “ngày đến”

- Khi kích chọn lần 2 để chọn ngày trên MonthCalendar, ngày được chọn sẽ hiện thị trong TextBox1 “ngày đi”.

Hình 5.25 Minh họa bài tập 2

Bài 3 Tạo Form gồm 1 DriveBox (Name: drvSource), 1 DirListBox

The application features a directory source (dirSource) alongside a file list box (fileSource) that accepts text files (*.txt) It includes a rich text box (rtxtFile) for displaying content and three buttons named btnFont, btnColor, and btnSave, which are labeled as Font, Color, and Save, respectively Additionally, the interface incorporates a FontDialog and a ColorDialog for user customization, as illustrated in figure 5.25.

- Khi kích chọn tập tin trong FileListBox thì nội dung của tập tin sẽ hiển thị trong RichTextBox

- Khi kích chọn vào nút lệnh Font, Hộp Font sẽ hiển thị để chọn Font cho vùng dữ liệu được bôi đen trên RichTextBox

- Khi kích chọn vào nút lệnh Color, Hộp màu sẽ hiển thị để chọn màu cho vùng dữ liệu được bôi đen trên RichTextBox

- Khi kích chọn vào nút lệnh Save, dữ liệu trên RichTextBox sẽ lưu vào bộ nhớ

Hình 5.26 Minh họa bài tập 3

- Tạo Form Thực đơn (Hình 5.26)chứa các công cụ:

Để hiển thị thông tin giá tiền cho các món ăn đã chọn trong bảng DANH MỤC MÓN ĂN, bạn chỉ cần nhấn nút OK Giá tiền của các món ăn bao gồm: Mực khô - 100, Gân kiệu - 200, Nem - 300, Chả - 400, Tré - 500, và Lạc rang - 600.

+ Nút lệnh Clear để hủy việc chọn lựa các món ăn

+ Nút lệnh Close để đóng Form thực đơn

Hình 5.27 Minh họa bài tập 4

HƯỚNG DẪN THỰC HIỆN BÀI TẬP

Bài 1 private void btnAdd_Click(object sender, EventArgs e)

{ listBox1.Items.Add(textBox1.Text); comboBox1.Items.Add(textBox1.Text); listBox1.SelectedItem = listBox1.Items[0]; textBox1.Clear(); textBox1.Focus(); btnDelete.Enabled = true; btnEdit.Enabled = true;

} else MessageBox.Show("Chọn màu thêm ở hộp màu", "Chú ý",

} private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { try

{ pictureBox1.BackColor Color.FromName(listBox1.SelectedItem.ToString()); comboBox1.Text = listBox1.SelectedItem.ToString();

{ pictureBox1.BackColor Color.FromName(listBox1.Items[0].ToString()); comboBox1.Text = listBox1.Items[0].ToString();

} private void btnClose_Click(object sender, EventArgs e)

} private void btnDelete_Click(object sender, EventArgs e) { try

{ comboBox1.Items.Remove(comboBox1.SelectedItem); listBox1.Items.Remove(listBox1.SelectedItem); listBox1.SelectedItem = listBox1.Items[0];

{ listBox1.Items.Clear(); comboBox1.Items.Clear(); comboBox1.Text = ""; pictureBox1.BackColor = Color.Transparent; btnDelete.Enabled = false; btnEdit.Enabled = false;

} private void btnEdit_Click(object sender, EventArgs e) { try

{ textBox1.Text = listBox1.SelectedItem.ToString(); comboBox1.Items.Remove(comboBox1.SelectedItem); listBox1.Items.Remove(listBox1.SelectedItem); listBox1.SelectedItem = listBox1.Items[0];

Trong MonthCalendar, kích chọn sự kiện DateSelected và đặt tên ChonNgay Đoạn mã được thực hiện như sau: public partial class frmChinh : Form

} private void ChonNgay(object sender, DateRangeEventArgs e)

{ textBox1.Text = monthCalendar1.SelectionStart.ToShortDateString(); kt = false;

{ textBox2.Text = monthCalendar1.SelectionEnd.ToShortDateString(); kt = true;

In the ToolBox, right-click on All Windows Form and select "Choose items " to sequentially select DirListBox, DriveListBox, and FileListBox The code is implemented as follows: private void drvSource_SelectedIndexChanged(object sender, EventArgs e).

} private void dirSource_SelectedIndexChanged(object sender, EventArgs e)

} private void fileSource_SelectedIndexChanged(object sender, EventArgs e)

{ rtxtFile.LoadFile(dirSource.Path + "\\" + fileSource.FileName,RichTextBoxStreamType.RichText);

} private void btnFont_Click(object sender, EventArgs e)

{ fontDialog1.ShowDialog(); rtxtFile.SelectionFont = fontDialog1.Font;

} private void btnColor_Click(object sender, EventArgs e)

{ colorDialog1.ShowDialog(); rtxtFile.SelectionColor = colorDialog1.Color;

} private void btnSave_Click(object sender, EventArgs e)

{ rtxtFile.SaveFile(dirSource.Path + "\\" + fileSource.FileName); }

Bài 4 Đoạn mã được thực hiện như sau: public partial class frmThucdon : Form

} private void BtnOK_Click(object sender, EventArgs e) { int i,s=0; for (i = 0; i < checkedListBox1.Items.Count; i++) if(checkedListBox1.GetItemChecked(i)) s += A[i];

} private void BtnClose_Click(object sender, EventArgs e)

} private void BtnClear_Click(object sender, EventArgs e) { for (int i = 0; i < checkedListBox1.Items.Count; i++) checkedListBox1.SetItemChecked(i, false);

FILE VÀ REGISTRY OPERATION

ĐỌC VÀ GHI FILE

Mục tiêu của bài viết là thực hiện các thao tác đọc và ghi vào file, một quá trình đơn giản nhưng không yêu cầu phải hiểu biết sâu về các đối tượng DirectoryInfo hoặc FileInfo Thay vào đó, chúng ta cần nắm vững một số lớp trình bày nội dung chung, được gọi là stream, mà chúng ta sẽ khám phá trong phần tiếp theo.

III.1.Streams Đọc và viết dữ liệu sẽ được thực hiện thông qua lớp stream Stream là dòng dữ liệu chảy đi Đây là một thực thể (entity) có khả năng nhận được hoặc tạo ra một

Lớp abstract System.IO.Stream định nghĩa các thành viên hỗ trợ việc đọc và viết dữ liệu một cách đồng bộ và không đồng bộ, cho phép thao tác với khối trữ tin, bao gồm cả tập tin trên đĩa và trong bộ nhớ.

Stream là một lớp trừu tượng, cho phép làm việc với các lớp dẫn xuất của nó, đại diện cho dữ liệu dưới dạng dòng bytes thô Các lớp này hỗ trợ chức năng truy tìm (seek), cho phép điều chỉnh vị trí trên dòng chảy dữ liệu Trước khi khám phá các chức năng của lớp Stream, bạn nên tìm hiểu về các thành viên của nó Ý tưởng về stream đã tồn tại từ lâu, và stream được sử dụng để chuyển dữ liệu theo hai hướng.

 Nếu dữ liệu được truyền từ nguồn bên ngoài vào trong chương trình của bạn, ta gọi là đọc dữ liệu

 Nếu dữ liệu được truyền từ chương trình của bạn ra nguồn bên ngoài, ta gọi là viết dữ liệu

Thường thì nguồn bên ngoài sẽ là một file, ngoài ra nó còn bao gồm cả trường hợp sau:

 Đọc hoặc ghi dữ liệu trên mạng dùng giao thức mạng

 Đọc hoặc ghi đến một đường ống chỉ định

 Đọc hoặc ghi đến một vùng của bộ nhớ

Hình 6.5 Các lớp có mối liên hệ trong namespace System.IO

III.2 Làm việc với Binary Files

Reading and writing to binary files thường được làm việc với lớp FileStream Làm việc với FileStream

Lớp FileStream cung cấp khả năng thi công cho các thành viên của lớp abstract Stream, cho phép xử lý file-base streaming một cách hiệu quả Tương tự như các lớp DirectoryInfo và FileInfo, FileStream cho phép mở các tập tin hiện có và tạo mới tập tin Khi tạo tập tin, lớp FileStream thường sử dụng các enum FileMode, FileAccess và FileShare để xác định chế độ truy cập và chia sẻ tập tin.

// tạo một tập tin mới trên thư mục làm việc

FileStream myFStream = new FileStream("test.dat",FileMode.OpenOrCreate, FileAccess.ReadWrite);

FileStream được sử dụng đọc và viết dữ liệu vào hoặc từ một file Để khởi tạo một FileStream, bạn cần 4 phần sau:

 file bạn muốn truy xuất

 mode, cho biết bạn muốn mở file như thế nào

 access, cho biết bạn muốn truy xuất file như thế nào – bạn định đọc hoặc viết file hoặc cả hai

 share access – khả năng truy xuất file

FileMode Append, Create, CreateNew, Open,

FileAccess Read, ReadWrite, or Write

FileShare Inheritable, None, Read, ReadWrite, or

Bảng 6.3 Để khởi tạo một FileStream

III.3 Làm việc với BufferedStream

Khi bạn gọi hàm Read(), hệ thống sẽ thực hiện việc đọc dữ liệu từ đĩa vào bộ đệm (buffer) Để tối ưu hiệu suất, hệ điều hành thường đọc một khối lượng lớn dữ liệu cùng lúc để tạm thời lưu trữ trên bộ đệm, hoạt động như một kho hàng.

Đối tượng Buffered stream cho phép hệ điều hành tạo một bộ đệm riêng để đọc và ghi dữ liệu lên ổ đĩa theo khối lượng tối ưu, giúp cải thiện hiệu suất Người dùng có thể xác định chiều dài khối dữ liệu, nhưng cần lưu ý rằng bộ đệm sẽ chiếm không gian trong bộ nhớ, không phải trên đĩa từ Việc sử dụng bộ đệm mang lại hiệu quả cao hơn trong quá trình xuất nhập dữ liệu.

BufferedStream là một đối tượng được xây dựng dựa trên một đối tượng Stream đã có Để sử dụng BufferedStream, trước tiên bạn cần tạo một đối tượng Stream thông thường, ví dụ: stream inputstream = File.OpenRead(@"C:\test\source\folder3.cs"); và stream outputstream = File.OpenWrite(@"C:\test\source\folder3.bak").

Một khi bạn đã có stream bình thường, bạn trao đối tượng này cho hàm constructor của buffere stream:

BufferedStrream bufInput = new BufferedStream(inputstream);

BufferedStream bufOutput =new BufferedStream(outputstream);

Sau khi sử dụng BufferedStream, bạn có thể gọi các hàm Read() hoặc Write() như bình thường Hệ điều hành sẽ tự động quản lý vùng đệm, ví dụ: while ((bytesRead = bufInput.Read(buffer, 0, SIZE_BUFF)) > 0).

Để đảm bảo dữ liệu được ghi lên đĩa, bạn cần nhớ một điều quan trọng là phải thực hiện lệnh tuôn ghi (flush) nội dung của bộ đệm Hãy sử dụng câu lệnh bufOutput.Flush(); để thực hiện điều này.

Lệnh trên bảo hệ điều hành lấy toàn bộ dữ liệu trên buffer cho tuôn ra ghi lên tập tin trên đĩa

III.4 Làm việc với những tập tin văn bản

Nếu bạn làm việc với file văn bản (đọc/viết) dạng dữ liệu kiểu string, hãy cân nhắc sử dụng lớp StreamReader và StreamWriter Cả hai lớp này hỗ trợ ký tự Unicode theo mặc định, nhưng bạn có thể tùy chỉnh bằng cách cung cấp một đối tượng cấu hình từ System.Text.Reference Tóm lại, StreamReader và StreamWriter được thiết kế để đơn giản hóa việc thao tác với các tập tin văn bản.

Lớp StreamReader được kế thừa từ lớp trừu tượng TextReader, tương tự như StringReader Lớp TextReader cung cấp các chức năng cơ bản cho các lớp con, đặc biệt là khả năng đọc và "liếc nhìn" (peek) vào dòng ký tự.

Lớp StreamWriter và StringWriter được kế thừa từ lớp trừu tượng TextWriter, lớp này xác định các thành viên cho phép các lớp con ghi dữ liệu văn bản vào một dòng văn bản cụ thể.

Các thành viên của lớp TextWriter

Close() Cho đóng lại các writer và giải phóng mọi nguồn lực chiếm dụng

Flush() Cho xoá sạch tất cả các buffer đối với writer hiện hành

NewLine Thuộc tính này dùng làm hằng sang hằng

Write() Viết một hằng lên text stream không có newline constant

WriteLine() Viết một hằng lên text stream có newline constant

Bảng 6.4 Các thành viên của lớp TextWriter

Ví dụ đọc, viết một tập tin văn bản:

The article illustrates how to use the StreamReader and StreamWriter classes in ReadWriteText It demonstrates reading a file and displaying its contents, as well as saving files in Unicode format.

Màn hình trình bày ReadWriteText được dùng hiển thị file CivNegotiations Chúng ta có thể đọc được ở nhiều định dạng file khác

Hình 6.6 Hiển thị file CivNegotiations

Đoạn mã dưới đây bắt đầu bằng câu lệnh "using", cho phép chúng ta sử dụng lớp StringBuilder từ namespace System.Text để xây dựng chuỗi trong textbox, bên cạnh System.IO.

Tiếp theo chúng ta thêm các trường cho lớp main form public class Form1 : System.Windows.Forms.Form

{ private OpenFileDialog chooseOpenFileDialog = new OpenFileDialog(); private string chosenFile;

Chúng ta cũng cần thêm vài chuẩn mã Windows Forms để thực hiện điều khiển cho menu và hộp thoại: public Form1()

InitializeComponent(); menuFileOpen.Click += new EventHandler(OnFileOpen); chooseOpenFileDialog.FileOk += new

} void OnFileOpen(object Sender, EventArgs e)

} void OnOpenFileDialogOK(object Sender, CancelEventArgs e)

{ chosenFile = chooseOpenFileDialog.FileName; this.Text = Path.GetFileName(chosenFile);

ĐỌC VÀ GHI VÀO REGISTRY

Mục tiêu: Sử dụng các mã lệnh để đọc, ghi vào Register

Registry trong Windows từ phiên bản 95 trở đi là nơi lưu trữ thông tin cấu hình quan trọng, bao gồm cài đặt hệ điều hành, sở thích người dùng, phần mềm cài đặt và thiết bị Hầu hết các phần mềm thương mại sử dụng Registry để lưu trữ thông tin của chúng, và các thành phần COM cần phải có thông tin trong Registry để được các ứng dụng khách gọi Mặc dù NET Framework đã giảm bớt sự phụ thuộc vào Registry nhờ vào khả năng tự cung tự cấp của assembly, nó vẫn là nơi tiện lợi để lưu trữ thông tin về sở thích người dùng Namespace Microsoft.Win32 cung cấp một số lớp giúp việc đọc và viết vào system registry trở nên dễ dàng hơn.

Trước tiên chúng ta cùng xem lại cấu trúc của Registry

Registry có cấu trúc tương tự như hệ thống tập tin Để xem hoặc chỉnh sửa nội dung Registry, người dùng có thể sử dụng hai công cụ: regedit.exe và regedt32.exe, có mặt trên tất cả các phiên bản Windows từ Windows 95 Regedt32.exe, chỉ có trong Windows NT và Windows 2000, ít thân thiện hơn regedit.exe nhưng cho phép truy cập thông tin an ninh mà regedit không thể Trong phần này, chúng ta sẽ sử dụng regedit.exe thông qua hộp thoại Run hoặc command prompt.

Khi bạn khởi chạy regedit đầu tiên bạn sẽ thấy hình sau đây:

Regedit có giao diện tương tự như treeview/listview trong Windows Explorer, phản ánh cấu trúc tổ chức của Registry Tuy nhiên, vẫn tồn tại một số điểm khác biệt đáng chú ý.

Trong một hệ thống file, các cấp chóp được coi là các phân vùng trên ổ đĩa như C:\, D:\, v.v Tương tự, trong Registry, các phân vùng này được gọi là registry hive Có tổng cộng bảy khuôn định nghĩa, và chúng không thể thay đổi.

HKEY_CLASSES_ROOT (HKCR) lưu trữ thông tin chi tiết về các loại tập tin như txt, doc và các ứng dụng có khả năng mở chúng Nó cũng chứa thông tin đăng ký cho tất cả các thành phần COM, chiếm phần lớn không gian của Registry do Windows tích hợp nhiều thành phần COM.

 HKEY_CURRENT_USER (HKCU) chứa chi tiết liên quan đến sở thích của người sử dụng hiện đang đang nhập trên máy tính

 HKEY_LOCAL_MACHINE (HKLM) là hive đồ sộ chứa chi tiết tất cả phần mềm và phấn cứng được cài đặt trên máy tính

HKEY_USERS (HKUSR) lưu trữ thông tin về sở thích của tất cả người dùng, đồng thời bao gồm hive HKCU, là một ánh xạ đến một trong những khóa trên HKEY_USERS.

 HKEY_CURRENT_CONFIG (HKCF) chứa đựng chi tiết liên quan đến phần cứng máy tính

Phần còn lại là hai key chứa thông tin mang tình trạng tạm thời và thay đổi thường xuyên:

 HKEY_DYN_DATA là một container tổng quát đối với bất cứ dữ liệu volatile nào cần lưu trữ đâu đó trên Registry

 HKEY_PERFORMANCE_DATA chứa thông tin liên quan đến thành tích ứng dụng đang chạy

Trong các hive, có một cấu trúc cây bao gồm các Registry key, tương tự như các thư mục và tệp trong hệ thống tệp Tuy nhiên, điểm khác biệt quan trọng là Registry chỉ chứa các key mà không phân biệt giữa tệp và thư mục Mỗi key có khả năng chứa dữ liệu và các key khác, và khi chứa dữ liệu, nó sẽ hiển thị dưới dạng một loạt các trị Mỗi trị bao gồm một tên, kiểu dữ liệu và giá trị, trong khi một key cũng có thể có một trị mặc định không được đặt tên.

Khóa HKCU\Control Panel\Appearance chứa 3 giá trị, mặc dù giá trị mặc định không có dữ liệu Cột Type mô tả kiểu dữ liệu của từng giá trị Các mục trong Registry có thể được định dạng theo một trong ba kiểu dữ liệu.

 REG_SZ gần như tương đương với NET string

 REG_DWORD gần như tương đương với NET unit

 REG_BINARY bản dãy các byte

2 .NET Registry Classes

Truy cập vào Registry trong NET được thực hiện thông qua hai lớp chính là Registry và RegistryKey trong không gian tên Microsoft.Win32 Mỗi thể hiện của lớp RegistryKey đại diện cho một registry key, cung cấp các thành viên cốt lõi để bạn thao tác với registry key một cách hiệu quả.

Lớp RegistryKey cho phép bạn làm việc với registry key, trong khi lớp Registry không được thể hiện trực tiếp Lớp Registry cung cấp các thể hiện RegistryKey cho các key top-level của các hive khác nhau thông qua 7 thuộc tính tĩnh: ClassesRoot, CurrentConfig, CurrentUser , DynData, LocalMachine, PerformanceData, và Users Mỗi thuộc tính này tương ứng với một registry hive cụ thể, ví dụ, để có một thể hiện của RegistryKey cho key HKLM, bạn có thể thực hiện theo cú pháp phù hợp.

Nếu bạn muốn đọc một vài dữ liệu trên key HKLM\Software\Microsoft, bạn phải đi lấy qui chiếu về key như sau :

RegistryKey hkSoftware = hklm.OpenSubKey("Software");

RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft");

Để có khả năng đọc và ghi lên một registry key, bạn cần sử dụng OpenSubkey với tham số thứ hai kiểu bool để chỉ định quyền read-write Nếu chỉ có quyền đọc, bạn sẽ không thể thay đổi giá trị của key, cũng như không thể tạo hoặc xóa các cây con Ví dụ, để thay đổi key của Microsoft, bạn cần đảm bảo rằng bạn đã thiết lập quyền ghi cho key đó.

RegistryKey hkSoftware = hklm.OpenSubKey("Software");

RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft", true);

Phương thức OpenSubKey() là hàm được sử dụng để truy cập một khóa trong registry, cho phép bạn kiểm tra sự tồn tại của khóa đó Nếu khóa không tồn tại, hàm sẽ trả về giá trị null.

145 muốn tạo một key mới bạn sẽ dùng CreateSubKey() (hàm này tự hoạt động cho quyền read write):

RegistryKey hkSoftware = hklm.OpenSubKey("Software");

RegistryKey hkMine = hkSoftware.CreateSubKey("MyOwnSoftware");

Khi bạn đã xác định được registry key cần đọc hoặc thay đổi, bạn có thể sử dụng các phương thức SetValue() hoặc GetValue() để thiết lập hoặc truy xuất dữ liệu từ key đó.

The code snippet creates a registry key named "MyOwnSoftware" and sets two values: "MyStringValue" with the data type REG_SZ containing the string "Hello World," and "MyIntValue" with the data type REG_DWORD set to the integer 20.

Hàm RegistryKey.GetValue() trả về một quy chiếu đối tượng, cụ thể là một chuỗi nếu kiểu dữ liệu là REG_SZ, và một số nguyên nếu kiểu dữ liệu là REG_DWORD Ví dụ, bạn có thể lấy giá trị chuỗi bằng cách sử dụng: `string stringValue = (string)hkMine.GetValue("MyStringValue");` và lấy giá trị số nguyên với: `int intValue = (int)hkMine.GetValue("MyIntValue");`.

Cuối cùng khi xong việc bạn phải cho đóng lại hkMine.Close();

Các thành phần của RegistryKey bao gồm thuộc tính và phương thức sau: Properties

Name Tên của key (read-only)

SubKeyCount số lượng sub key

ValueCount Các trị trên key

CreateSubKey() Tạo một subkey của một tên được cho

DeleteSubKey() Bỏ một key được chỉ định

DeleteSubKeyTree() Gỡ bỏ một cách đệ quy một subkey

DeleteValue() Tháo bỏ một tên trị từ một key

GetSubKeyNames() Trả về một dãy chuỗi chứa tên của subkeys

GetValue() Trả về một tên trị

GetValueNames() Trả về một dãy chuỗi chứa tên của tất cả các trị của key

OpenSubKey() Trả về một tham khảo đến một RegistryKey,hàm này cho tìm lại subkey SetValue() Hàm này cho đặt một trị được chỉ định

ĐỒ HOẠ VÀ MỘT SỐ XỬ LÝ NÂNG CAO

GIỚI THIỆU VỀ LỚP GRAPHICS

Mục tiêu: Liệt kê được các thành phần chính của không tên đồ hoạ; Trình bày môi trường làm việc đồ hoạ của NET Framework

Trước khi vẽ các hình ảnh đồ họa như đường, hình, ảnh và văn bản bằng GDI+, cần tạo một đối tượng Graphics để thực hiện các thao tác vẽ.

Một số hàm vẽ và tô màu với Graphisc:

FillEllipse Fills the interior of an ellipse defined by a bounding rectangle FillPath Fills the interior of a path

FillPie Fills the interior of a pie section

FillPolygon Fills the interior of a polygon defined by an array of points

FillRectangle Fills the interior of a rectangle with a Brush

FillRectangles Fills the interiors of a series of rectangles with a Brush

FillRegion Fills the interior of a Region

Bảng 7.1 Một số hàm vẽ và tô màu với Graphisc

Hình 7.2 Một số hàm vẽ

KHỞI TẠO CÁC ĐỐI TƯỢNG GRAPHIC

- Trình bày môi trường làm việc đồ hoạ của NET Framework;

- Trình bày được cấu pháp để thực hiện các đối tượng đồ hoạ trong C#;

Chúng ta có thể tạo ra các đối tượng đồ họa bằng các cách sau:

 Sử dụng phương thức CreateGraphisc()

 Sử dụng Object được dẫn xuất từ lớp Image

 private void Form1_Paint(object sender, PaintEventArgs e)

Pen p = new Pen(Color.Blue); g.DrawEllipse(p, new Rectangle(10, 10, 50, 50));

 protected override void OnPaint(PaintEventArgs e)

Pen p = new Pen(Color.Blue); g.DrawEllipse(p, new Rectangle(60, 60, 50, 50));

Sử dụng phương thức CreateGraphics()

Pen p = new Pen(Color.Blue); g.DrawEllipse(p, new Rectangle(60, 60, 100, 100));

Sử dụng Object được dẫn xuất từ lớp Image

Size _fullSize = SystemInformation.PrimaryMonitorMaximizedWind owSize;

Bitmap _bitmap = new Bitmap(_fullSize.Width, _fullSize.Height); _g = Graphics.FromImage(_bitmap);

CÁC ĐỐI TƯỢNG GRAPHIC

- Thiết lặp được toạ độ, các thuộc tính của các đối tượng đồ hoạ;

- Vẽ được các đối tượng đồ hoạ;

 Dùng để vẽ các đường thẳng, đường cong hay các hình với màu sắc, độ dày nét vẽ hay 1 style tùy chọn

 Graphics cung cấp các phương thức để vẽ như DrawRectangle,

DrawlEllipse…Còn Pen cho phép bạn xác định màu vẽ , kiểu kiểu vẽ và độ dày nét vẽ…

Hình 7.3 Một số hàm Constructor

Hình 7.3 Một số thuộc tính

Hình 7.4 Kết quả chương trình

 Để tô các đối tượng đồ họa như hình chữ nhật, ellipse

 Graphics cung cấp các phương thức để tô như FillRectangle , FillEllipse…Còn Brush cho phép bạn xác định màu tô , kiểu tô…

 Brush là một abstract class vì thế nó không được tạo ra như một đối tượng mà cần phải sử dụng các class con của nó

 Trong GDI+ có tất cả 5 loại chổi vẽ (Brush):

Hình 7.6 5 loại chổi vẽ (Brush)

 SolidBrush: tô với 1 màu duy nhất

Hình 7.7 Kết quả chương trình

 TextureBrush: -Tô với chất liệu lấy từ một tập tin ảnh bất kỳ

Hình 7.8 Kết quả chương trình

 Tô với mẫu có sẵn

 Các mẫu tô lấy từ enum HatchStyle

Hình 7.9 Kết quả chương trình

LinearGradientBrush là công cụ tô màu giúp tạo ra hiệu ứng chuyển màu mượt mà từ màu này sang màu khác Sự chuyển tiếp màu sắc bắt đầu từ một cạnh của hình và lan tỏa dần đến cạnh đối diện, mang lại vẻ đẹp hài hòa cho thiết kế.

Hình 7.10 Kết quả chương trình

 PathGradientBrush: -Giống như LinearGradientBrush nhưng sự chuyển tiếp màu bắt đầu từ giữa hình rồi lan dần ra bên ngoài

Hình 7.11 Kết quả chương trình

Font là tập hợp đầy đủ các ký tự như chữ cái, dấu câu, số và ký hiệu đặc biệt, được tổ chức theo kiểu dáng, định dạng (thường hoặc đậm), hình thức (thẳng hoặc nghiêng) và kích cỡ khác nhau để tạo sự phân biệt.

Các loại Font trên HĐH Windows:

 Class Font: Dùng để xác định cách định dạng văn bản

Hình 7.12 Kết quả chương trình

Hình 7.13 Kết quả chương trình

Hình 7.14 Kết quả chương trình

Trong GDI+,color được biểu diễn bởi một cấu trúc gồm bốn thành phần:

 Chứa nhiều property đại diện cho các màu

Hình 7.15 Kết quả chương trình

Hổ trợ các phương thức tĩnh để tạo đối tượng Color:

 Color.FromArgb: Trả về đối tượng Color với các giá trị tương ứng

Hình 7.16 Kết quả chương trình

 Color.FromName: Trả về đối tượng Color được định nghĩa sẵn có tên tương ứng

Hình 7.17 Kết quả chương trình

Hình 7.18 Kết quả chương trình

III.5 Giới thiệu về Bitmap

Trong đồ họa máy vi tính, BMP, hay còn gọi là Windows bitmap, là một định dạng tập tin hình ảnh phổ biến Các tập tin đồ họa lưu dưới định dạng BMP thường có đuôi BMP hoặc DIB (Device Independent Bitmap).

Hình 7.20 Kết quả chương trình

Hình 7.21 Kết quả chương trình

CÁC CHỦ ĐỀ NÂNG CAO TRONG GDI+

- Thiết lặp được toạ độ, các thuộc tính của các đối tượng đồ hoạ nâng cao;

- Vẽ được các đối tượng đồ hoạ;

- Dùng ngôn ngữ C# để xây dựng để xây dựng các ứng dụng đồ hoạ ở Chế độ tô vẽ và vẽ mượt mà (Antialiasing), Double buffering

Antialiasing là kỹ thuật làm mượt các góc cạnh trên hình dáng và văn bản bằng cách thêm bóng tại đường viền Ví dụ, việc thêm bóng màu xám vào đường cong màu đen giúp tạo ra góc cạnh mềm mại hơn Kỹ thuật này hoạt động bằng cách trộn lẫn đường cong với nền của nó.

Hình 7.22 Kết quả chương trình

Hình 7.23 Kết quả chương trình

IV.2 Kỹ thuật Double Buffering

Trong quá trình xử lý đồ họa, có những tình huống yêu cầu chúng ta phải vẽ lại nhiều lần các bức hình với cường độ cao Tình trạng này có thể gây ra những vấn đề về hiệu suất và chất lượng hình ảnh.

Double Buffering sẽ làm giảm sự “nháng hình” đó

Kỹ thuật "double buffering" cho phép logic vẽ ghi lại một hình bitmap trong bộ nhớ, sau đó sao chép hình này lên form thông qua một thao tác vẽ lại duy nhất Nhờ đó, hiện tượng rung hình được giảm thiểu đáng kể.

Trong NET, có vài cách đơn giản để kích hoạt chế độ Double Buffering:

Hình 7.24 Kích hoạt chế độ Double Buffering

CÂU HỎI VÀ BÀI TẬP

Chương trình này cho phép người dùng vẽ các hình cơ bản như hình tròn, hình chữ nhật và hình elip trên giao diện form Bên cạnh đó, người dùng có thể tùy chọn màu sắc để tô màu cho các hình vẽ, tạo ra những tác phẩm nghệ thuật độc đáo.

TRUY XUẤT DỮ LIỆU VỚI ADO.NET

GIỚI THIỆU VỀ LẬP TRÌNH CƠ SỞ DỮ LIỆU

Mục tiêu: Trình bày công cụ lập trình ADO.NET

ADO.NET, giống như nhiều thành phần khác của NET Framework, không chỉ đơn thuần là một lớp bọc cho các API có sẵn Mặc dù mang tên ADO, nhưng các lớp và phương thức truy xuất dữ liệu của nó hoàn toàn khác biệt.

ADO (Microsoft ActiveX Data Objects) là thư viện các thành phần COM được đánh giá cao trong những năm gần đây Phiên bản mới nhất hiện nay là 2.7, với các thành phần chính bao gồm Connection, Command, Recordset và Field.

Một kết nối có thể mở cơ sở dữ liệu và chọn một số dữ liệu vào một recordset, bao gồm các trường, cho phép thao tác và cập nhật lên server Sau khi hoàn tất, kết nối cần được đóng lại ADO cũng cung cấp một recordset không kết nối, được sử dụng khi không cần duy trì kết nối trong thời gian dài.

Một số vấn đề với ADO bao gồm sự không hài lòng về địa chỉ và sự cồng kềnh của một recordset không kết nối Hỗ trợ cho những vấn đề này trở nên không cần thiết do sự tiến hóa của công nghệ thông tin.

ADO.NET là một công nghệ quan trọng trong lập trình web, giúp dễ dàng chuyển đổi từ ADO mà không gặp nhiều khó khăn Đặc biệt, khi sử dụng SQL Server, ADO.NET cung cấp một bộ công cụ mạnh mẽ để thao tác dữ liệu bên ngoài cơ sở dữ liệu, làm tăng hiệu quả và khả năng quản lý dữ liệu Những lý do này khiến ADO.NET trở thành một lựa chọn hấp dẫn cho các lập trình viên.

ADO.NET cung cấp hai không gian tên cơ sở dữ liệu: một cho SQL Server và một cho các cơ sở dữ liệu qua giao diện OLE DB Nếu bạn sử dụng OLE DB cho cơ sở dữ liệu của mình, việc kết nối từ NET trở nên đơn giản với các lớp OLE DB và driver cơ sở dữ liệu hiện hành.

Kiến trúc của ADO.NET

Có hai thành phần chính của ADO.NET là truy cập và thao tác dữ liệu:

.NET Framework data providers are designed for fast, one-way, read-only access to various types of data They consist of a collection of data drivers within the Connectivity Layer architecture.

Trong chương này, tất cả các ví dụ đều liên quan đến việc truy xuất dữ liệu theo nhiều cách khác nhau Các không gian tên dưới đây chỉ ra các lớp và giao diện được sử dụng cho việc truy xuất dữ liệu trong NET.

 System.Data - Các lớp truy xuất dữ liệu chung

 System.Data.Common - Các lớp dùng chung bởi các data provider khác nhau

 System.Data.OleDb - Các lớp của OLE DB provider

 System.Data.SqlClient - Các lớp của SQL Server provider

 System.Data.SqlTypes - Cac kiểu của SQL Server

Các lớp chính trong ADO.NET được liệt kê dưới đây:

ADO.NET chứa một số lớp được dùng không quan tâm là bạn đang dùng các lớp của SQL Server hay là các lớp của OLE DB

Các lớp trong không gian tên System.Data được liệt kê sau đây:

DataSet là một đối tượng chứa nhiều DataTable, cho phép quản lý các mối quan hệ giữa các bảng Nó được thiết kế để hỗ trợ truy xuất dữ liệu không kết nối một cách hiệu quả.

 DataTable - Một kho chứa dữ liệu Một DataTable bao gồm một hoặc nhiều DataColumns, và khi được tạo ra nó sẽ có một hoặc nhiều DataRows chứa dữ liệu

 DataRow - Một bộ giá trị, có bà con với một dòng trong bảng cơ sở dữ liệu, hoặc một dòng của bảng tính

 DataColumn - Chứa cá định nghĩa của một cột, chẳng hạn như tên và kiểu dữ liệu

 DataRelation - Một liên kết giữa hai DataTable trong một DataSet Sử dụng cho khóa ngoại và các mối quan hệ chủ tớ

 Constraint - Định nghĩa một qui tắt cho một DataColumn (hoặc môt bộ các cột dữ liệu), như các giá trị là độc nhất

Sau đây là hai lớp được tìm thấy trong không gian tên System.Data.Common:

 DataColumnMapping - Ánh xạ tên của một cột từ cơ sở dữ liệu vào tên của một cột trong một DataTable

 DataTableMapping - Ánh xạ tên của một bảng từ cơ sở dữ liệu vào một bảng trong một DataSet

I.3 Các lớp cơ sở dữ liệu chuyên biệt

ADO.NET cung cấp một số lớp dữ liệu chuyên biệt bổ sung cho các lớp dùng chung, thực thi các giao diện chuẩn trong không gian tên System.Data Điều này cho phép sử dụng các lớp với kiểu giao diện tương tự, chẳng hạn như SqlConnection và OleDbConnection đều thực thi giao diện IDbConnection.

 SqlCommand, OleDbCommand - Một vỏ bọc của các câu lệnh SQL hoặc các lời gọi stored procedure

 SqlCommandBuilder, OleDbCommandBuilder - Một lớp sử dụng các câu lệnh SQL (chẳng hạn như các câu lệnh INSERT, UPDATE, vàDELETE) từ một câu lệnh SELECT

 SqlConnection, OleDbConnection - Kết nối với cơ sở dữ liệu Giống như một ADO Connection

 SqlDataAdapter, OleDbDataAdapter - Một lớp giữ các câu lệnh select, insert, update, và delete, chúng được sử dụng để tạo một DataSet và cập nhật Database

 SqlDataReader, OleDbDataReader - Chỉ đọc, kết nối với data reader

 SqlParameter, OleDbParameter - Định nghĩa một tham số cho một stored procedure

 SqlTransaction, OleDbTransaction - Một giao tiếp cơ sở dữ liện, được bọc trong một đối tượng

Các lớp ADO.NET được thiết kế để hoạt động trong môi trường không kết nối, đóng vai trò quan trọng trong thế giới "web-centric" Chúng được sử dụng để kiến trúc các server, chẳng hạn như trong việc mua sách trực tuyến, cho phép kết nối với server, lấy dữ liệu, xử lý trên PC khách và sau đó truyền dữ liệu trở lại để xử lý.

ADO 2.1 giới thiệu recordset không kết nối, nó cho phép dữ liệu có thể được lấy từ một cơ sở dữ liệu, được truyền cho trình khách để xử lí Nó thường khó xử dụng do cách ứng xử không kết không được thiết kế từ đâu Các lớp ADO.NET thì khác - Sql/OleDb DataReader được thiết kết cho để dùng cho các cơ sở dữ liệu offline

Trong bài viết này, chúng tôi sẽ trình bày cách sử dụng các lớp và giao diện để truy cập cơ sở dữ liệu Tập trung chủ yếu vào các lớp Sql khi kết nối với cơ sở dữ liệu, vì các ví dụ được triển khai trên hệ thống MSDE (SQL Server) Trong nhiều trường hợp, các lớp OleDb cũng hoạt động tương tự như mã Sql.

ĐỐI TƯỢNG SQL

II.2 Không gian tên Microsoft.SqlServer

II.3 Làm việc với Microsoft.SqlServer.Management

II.4 Thư viện SqlServer.Management

II.5 Thao tác dữ liệu

SỬ DỤNG CÁC DATABASE CONNECTION

Mục tiêu: Mô tả và lập trình với đối tượng Connection

Để truy xuất cơ sở dữ liệu, bạn cần cung cấp thông số kết nối, bao gồm thiết bị chạy cơ sở dữ liệu và thông tin đăng nhập Những người đã làm việc với ADO sẽ dễ dàng làm quen với các lớp kết nối trong NET, như OleDbConnection và SqlConnection.

The following code demonstrates how to create, open, and close a connection to the Northwind database using OleDbConnection and SqlConnection This chapter utilizes the Northwind database, which is commonly installed with the NET Framework SDK examples The code snippet begins with the necessary using directive for System.Data.SqlClient and specifies the connection string as "server=(local)\\NetSDK;".

SqlConnection conn = new SqlConnection(source); conn.Open();

// Do something useful conn.Close();

Chuỗi kết nối trở nên dễ sử dụng cho những ai đã quen thuộc với ADO hoặc OLE DB, cho phép bạn dễ dàng sao chép mã từ các ứng dụng trước đây nếu sử dụng OleDb provider Trong ví dụ này, các tham số trong chuỗi kết nối được phân cách bởi dấu chấm phẩy.

Kết nối đến máy chủ cơ sở dữ liệu được biểu diễn bởi server=(local)\\NetSDK, cho phép nhiều tiến trình cơ sở dữ liệu SQL Server chạy trên cùng một máy Trong trường hợp này, chúng ta thực hiện kết nối với tiến trình NetSDK trên máy cục bộ.

 uid=QSUser - Tham số này mô tả người dùng cơ sở dữ liệu Bạn cũng có thể sử dụng User ID

Trong quá trình cài đặt các ví dụ NET, người dùng sẽ sử dụng mật khẩu "QSPassword" để truy cập .NET SDK cung cấp một bộ các cơ sở dữ liệu đồng nhất, và thông tin người dùng/mật khẩu này được liên kết chặt chẽ với quá trình cài đặt Bạn cũng có thể sử dụng mật khẩu khác nếu cần.

 database=Northwind - Cái này mô tả loại dữ liệu để kết nối - mỗi tiến trình SQL Server có thể đưa ra một vài loại dữ liệu khác nhau

Bài viết này mô tả quy trình mở và đóng kết nối cơ sở dữ liệu bằng chuỗi kết nối đã được định nghĩa Khi kết nối được thiết lập, bạn có thể thực hiện các lệnh để thao tác trên cơ sở dữ liệu Sau khi hoàn tất các thao tác, kết nối có thể được đóng lại.

SQL Server hỗ trợ chế độ bảo mật của Windows, cho phép khả năng truy cập của Windows được áp dụng cho SQL Server Khi sử dụng tùy chọn này, bạn có thể loại bỏ thông tin uid và pwd trong chuỗi kết nối, thay vào đó thêm Integrated Security=SSPI.

Khi tải mã nguồn cho chương này, hãy tìm file Login.cs, vì nó đơn giản hóa các ví dụ File này kết nối với tất cả mã ví dụ và chứa thông tin kết nối cơ sở dữ liệu Bạn cần cung cấp tên server, user và password phù hợp; nếu sử dụng Windows integrated security mặc định, hãy thay đổi username và password cho đúng.

Trước khi chuyển sang chủ đề khác, chúng ta cần xem xét một số thực hành tốt liên quan đến việc mở kết nối.

III.1 Sử dụng hiệu quả các Connection

Khi sử dụng các tài nguyên hiếm trong NET như kết nối cơ sở dữ liệu, cửa sổ hoặc đối tượng đồ họa, việc đảm bảo đóng chúng sau khi sử dụng là rất quan trọng Điều này giúp tối ưu hóa hiệu suất và tránh rò rỉ tài nguyên.

Các nhà thiết kế của NET có khả năng quản lý bộ nhớ hiệu quả nhờ vào trình thu gom rác, công cụ này sẽ tự động giải phóng bộ nhớ sau một khoảng thời gian nhất định Tuy nhiên, việc giải phóng bộ nhớ nên được thực hiện càng sớm càng tốt để tối ưu hóa hiệu suất.

Khi viết mã truy xuất cơ sở dữ liệu, việc giữ kết nối ngắn hạn là rất quan trọng để không ảnh hưởng đến các phần khác của ứng dụng Nếu không đóng kết nối, người dùng khác có thể bị khóa truy cập vào các bảng dữ liệu, gây ảnh hưởng nghiêm trọng đến hiệu suất Do đó, việc đóng kết nối cơ sở dữ liệu là bắt buộc, và bài viết này sẽ hướng dẫn cách cấu trúc mã để giảm thiểu rủi ro cho mã nguồn mở.

Có hai cách để đảm bảo rằng các kết nối cơ sở dữ liệu được giải phóng sau khi dùng

III.2 Tùy chọn một - try/catch/finally

Để đảm bảo rằng các tài nguyên được giải phóng đúng cách, bạn nên sử dụng các khối lệnh try…catch…finally và đảm bảo rằng các kết nối được đóng trong khối lệnh finally.

// Open the connection conn.Open();

// Do something about the exception

// Ensure that the connection is freed conn.Close ( ) ;

Khối kết nối cho phép bạn giải phóng tài nguyên đã sử dụng, nhưng cần lưu ý đảm bảo đóng các kết nối Việc quên thêm khối finally có thể xảy ra, vì vậy việc tuân thủ phong cách lập trình tốt là rất quan trọng.

Bạn có thể mở nhiều tài nguyên như hai kết nối cơ sở dữ liệu và một file trong một phương thức, nhưng điều này có thể làm cho các khối try…catch…finally trở nên khó đọc Một giải pháp thay thế để đảm bảo dọn dẹp tài nguyên là sử dụng câu lệnh.

III.3 Tùy chọn hai - Sử dụng khối câu lệnh

COMMANDS

Mục tiêu: Trình bày và thực thi đối tượng Command

Commands are simple SQL statements used to retrieve data They can take the form of a stored procedure or refer to the name of a table For example, a command might look like this: string source = "server=(local)\\NetSDK;".

"uid=QSUser;pwd=QSPassword;" + "database=Northwind"; string select = "SELECT ContactName,CompanyName FROM Customers";

SqlConnection conn = new SqlConnection(source); conn.Open();

SqlCommand cmd = new SqlCommand(select, conn);

SqlCommand and OleDbCommand are commonly referred to as CommandType, which are used to define SQL statements, stored procedures, or SQL commands Below is a simple table listing CommandType.

String select = "SELECT ContactName FROM Customers"; SqlCommand cmd = new SqlCommand(select , conn);

StoredProcedure SqlCommand cmd = new SqlCommand("CustOrderHist", conn); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@CustomerID", "QUICK");

TableDirect OleDbCommand cmd = new OleDbCommand("Categories", conn); cmd.CommandType = CommandType.TableDirect;

Khi thực thi một stored procedure, việc truyền tham số là cần thiết, như ví dụ với tham số @CustomerID Có nhiều cách để cài đặt giá trị cho tham số, và chúng ta sẽ thảo luận chi tiết hơn trong phần sau của chương này Lưu ý rằng kiểu TableDirect command không chỉ áp dụng cho OleDb provider; có một ngoại lệ khi sử dụng command này với Sql provider.

Để thực thi các command đã định nghĩa, bạn có thể sử dụng các mệnh đề SqlCommand và OleDbCommand với các phương thức thực thi khác nhau, tùy thuộc vào kết quả mà bạn mong muốn nhận được.

 ExecuteNonQuery() – Thực thi các command không trả về kết quả gì cả

 ExecuteReader() – Thực thi các command và trả về kiểu IDataReader

 ExecuteScalar() – Thực thi các command và trả về một giá trị đơn

Lớp SqlCommand cung cấp thêm một số phương thức sau

 ExecuteXmlReader() – Thực thi các command trả về một đối tượng XmlReader, các đối tượng được dùng đề xem xét các XML được trả về từ cơ sở dữ liệu

Phương thức này thường được áp dụng cho các câu lệnh UPDATE, INSERT hoặc DELETE, nhằm trả về số lượng bản ghi bị ảnh hưởng Nó có khả năng trả về kết quả thông qua các tham số được truyền vào stored procedure.

{ public static void Main(string[] args)

{ string source = "server=(local)\\NetSDK;" +

"database=Northwind"; string select = "UPDATE Customers " + "SET ContactName = 'Bob' " + "WHERE ContactName = 'Bill'";

SqlConnection conn = new SqlConnection(source); conn.Open();

SqlCommand cmd = new SqlCommand(select, conn); int rowsReturned = cmd.ExecuteNonQuery();

Console.WriteLine("{0} rows returned.", rowsReturned); conn.Close();

ExecuteNonQuery() trả về một số kiểu int cho biết số dòng bị tác động command

This method executes commands that return a SqlDataReader or OleDbDataReader object This object can be used to generate records, as demonstrated in the following code: using System; using System.Data.SqlClient; public class ExecuteReaderExample.

{ public static void Main(string[] args)

{ string source = "server=(local)\\NetSDK;" +

"database=Northwind"; string select = "SELECT ContactName,CompanyName FROM Customers"; SqlConnection conn = new SqlConnection(source); conn.Open();

SqlCommand cmd = new SqlCommand(select, conn);

SqlDataReader reader = cmd.ExecuteReader(); while(reader.Read())

Console.WriteLine("Contact : {0,-20} Company : {1}" , reader[0] , reader[1]);

Hình 8.2 Kết quả chương trình

Các đối tượng SqlDataReader và OleDbDataReader sẽ được trình bày trong chương sau

Trong nhiều trường hợp, câu lệnh SQL cần trả về kết quả đơn, như số lượng bản ghi trong bảng hoặc thời gian hiện tại của server Phương thức ExecuteScalar là giải pháp phù hợp cho những tình huống này.

{ public static void Main(string[] args)

{ string source = "server=(local)\\NetSDK;" +

"database=Northwind"; string select = "SELECT COUNT(*) FROM Customers";

SqlConnection conn = new SqlConnection(source); conn.Open();

SqlCommand cmd = new SqlCommand(select, conn); object o = cmd.ExecuteScalar();

Phương thức trả về một đối tượng, Bạn có thể chuyển sang kiểu thích hợp

IV.1.4 ExecuteXmlReader() (SqlClient Provider Only)

Giống như tên gọi, XmlReader có khả năng thực thi lệnh và trả về một đối tượng SQL Server hỗ trợ câu lệnh SQL SELECT với kiểu FOR XML Mệnh đề này có ba tùy chọn khác nhau.

 FOR XML AUTO – tạo một cây cơ sở cho các bảng trong mệnh đề FROM

 FOR XML RAW – trả về một bộ các mẫu tin ánh xạ đệnh các nhân tố, với các cột được ánh xạ đến các thuộc tính

 FOR XML EXPLICIT – bạn cần phải chỉ định hình dạng của cây XML trả về

Professional SQL Server 2000 XML (Wrox Press, ISBN 1-861005-46-6) diễn tả đầy đủ các thuộc tính này: using System; using System.Data.SqlClient; using System.Xml; public class ExecuteXmlReaderExample

{ public static void Main(string[] args)

{ string source = "server=(local)\\NetSDK;" +

"database=Northwind"; string select = "SELECT ContactName,CompanyName " +

"FROM Customers FOR XML AUTO";

SqlConnection conn = new SqlConnection(source); conn.Open();

SqlCommand cmd = new SqlCommand(select, conn);

XmlReader xr = cmd.ExecuteXmlReader(); xr.Read(); string s; do

Chúng ta có thể sử dụng không gian tên System.Xml để làm việc với các kiểu trả về XML trong NET Framework Không gian này sẽ được trình bày chi tiết trong chương 11 Nó bao gồm các mệnh đề FOR XML AUTO trong SQL và phương thức ExecuteXmlReader() Dưới đây là kết quả của các mã lệnh này.

Hình 8.4 Kết quả chương trình

Trong mệnh đề SQL, chúng ta có thể chỉ định các thành phần của kiểu Customers để hiển thị trong kết quả Để thực hiện điều này, cần thêm các thuộc tính cho từng cột trong cơ sở dữ liệu, dẫn đến việc phân mảnh khi chọn các mẫu tin từ cơ sở dữ liệu.

IV.2.Gọi các Stored Procedure

Gọi một stored procedure với đối tượng command chỉ cần định nghĩa tên của stored procedure và thêm các tham số cần thiết Sau đó, thực thi command bằng một trong các phương thức đã nêu Để minh họa, tôi đã tạo một bộ stored procedures để chèn, cập nhật và xóa các mẫu tin từ bảng Region trong cơ sở dữ liệu Northwind, vì bảng này đủ nhỏ để dễ dàng áp dụng ví dụ cho từng loại stored procedure.

IV.2.1 Gọi một Stored Procedure không trả lại kết quả

Bài viết này mô tả cách gọi một stored procedure không trả lại kết quả, với hai procedure được định nghĩa: một để cập nhật các mẫu Region hiện có và một để xóa các bản ghi trong Region.

Cập nhật một mẫu Region là công việc đơn giản, chỉ cần thay đổi một trường duy nhất do không thể cập nhật khóa chính Bạn có thể nhập trực tiếp các ví dụ này trong SQL Server Query Analyzer để cài đặt các stored procedure cần thiết cho phần này.

CREATE PROCEDURE RegionUpdate (@RegionID INTEGER,

Một stored procedure trong cơ sở dữ liệu cần cập nhật trạng thái của các mẫu bằng cách sử dụng hai tham số là @RegionID và @RegionDescription Lệnh UPDATE sẽ được phát ra để thực hiện thao tác này Để chạy stored procedure trong mã NET, bạn cần định nghĩa và thực thi một lệnh SQL tương ứng.

SqlCommand aCommand = new SqlCommand("RegionUpdate", conn); aCommand.CommandType = CommandType.StoredProcedure; aCommand.Parameters.Add(new SqlParameter ("@RegionID",

SqlDbType.Int, 0, "RegionID")); aCommand.Parameters.Add(new SqlParameter("@RegionDescription",

The code snippet creates a new SqlCommand object named aCommand and defines it as a stored procedure It then adds input parameters as well as parameters to capture the desired return values from the stored procedure The details regarding the values in the UpdateRowSource rows will be discussed further in the subsequent sections of this chapter.

TRUY CẬP NHANH CƠ SỞ DỮ LIỆU VỚI DATA READER

Mục tiêu: Mô tả và thực thi đối tượng data reader để lập trình với CSDL

Một data reader là phương pháp đơn giản và nhanh chóng để truy xuất dữ liệu từ cơ sở dữ liệu, mặc dù nó có ít tính năng hơn Bạn có thể nhận được một đối tượng data reader trực tiếp từ SqlCommand hoặc OleDbCommand thông qua phương thức ExecuteReader() Đối tượng trả về có thể là SqlDataReader từ SqlCommand hoặc OleDbDataReader từ OleDbCommand.

Mã lệnh dưới đây minh họa cách lấy dữ liệu từ bảng Customers trong cơ sở dữ liệu Northwind Ví dụ này cho thấy cách kết nối với cơ sở dữ liệu, chọn một số bản ghi, duyệt qua các bản ghi đã chọn và hiển thị chúng trên màn hình console.

Ví dụ này minh họa cách sử dụng OLE DB provider, trong đó các phương thức của SqlClient thường được ánh xạ trực tiếp vào các phương thức của OleDBClient Để thực hiện các lệnh đối với nguồn dữ liệu OLE DB, lớp OleDbCommand được sử dụng Dưới đây là mã lệnh mẫu cho một câu lệnh SQL đơn giản, cho phép đọc các mẫu tin trả về từ đối tượng OleDbDataReader.

Mã ví dụ có sẵn trong thư mục Chapter 09\03_DataReader Lưu ý rằng hai câu lệnh using sau đây được sử dụng trong lớp OleDb: using System; và using System.Data.OleDb;.

All data providers are included within the data DLLs, so simply referencing the System.Data.dll assembly allows for the use of the classes in this section, such as the public class DataReaderExample.

{ public static void Main(string[] args)

"database=northwind"; string select = "SELECT ContactName,CompanyName FROM Customers"; OleDbConnection conn = new OleDbConnection(source); conn.Open();

OleDbCommand cmd = new OleDbCommand(select , conn);

OleDbDataReader aReader = cmd.ExecuteReader(); while(aReader.Read())

Console.WriteLine("'{0}' from {1}" , aReader.GetString(0) , aReader.GetString(1)); aReader.Close(); conn.Close();

Đoạn mã nguồn này bao gồm các lệnh quen thuộc từ các chương trước Để biên dịch ví dụ này, sử dụng lệnh sau: csc /t:exe /debug+ DataReaderExample.cs /r:System.Data.dll.

Mã sau đây từ ví dụ trên cho phép tạo một kết nối OLE DB NET, dựa trên chuỗi kết nối:

OleDbConnection conn = new OleDbConnection(source); conn.Open();

OleDbCommand cmd = new OleDbCommand(select, conn);

The third line creates a new OleDbCommand object based on the SELECT statement, which the connection will execute If you create a valid command, you can execute it to return an OleDbDataReader instance.

OleDbDataReader là một con trỏ "connected" cho phép bạn duyệt qua các mẫu tin được trả về Kết nối hiện tại sẽ giữ lại các mẫu tin này cho đến khi data reader được đóng lại.

Lớp OleDbDataReader không thể được khởi tạo trực tiếp; thay vào đó, nó được trả về thông qua phương thức ExecuteReader() của lớp OleDbCommand Có nhiều cách khác nhau để truy cập dữ liệu trong OleDbDataReader sau khi mở nó.

Khi đối tượng OleDbDataReader được đóng lại thông qua phương thức Close() hoặc quá trình thu dọn rác, kết nối bên dưới có thể cũng bị đóng lại thông qua lệnh ExecuteReader() Nếu bạn sử dụng ExecuteReader() với tham số CommandBehavior.CloseConnection, bạn có thể đảm bảo rằng kết nối sẽ tự động đóng lại khi reader được đóng.

Lớp OleDbDataReader cung cấp quyền truy xuất dữ liệu thông qua các mảng quen thuộc như object o = aReader[0]; và object o = aReader["CategoryID"]; trong đó CategoryID là trường đầu tiên trong câu lệnh SELECT Mặc dù cả hai cách đều thực hiện chức năng tương tự, cách truy xuất theo tên trường (cách hai) có thể chậm hơn một chút so với cách truy xuất theo chỉ số (cách một) Để minh họa, tôi đã phát triển một ứng dụng đơn giản thực hiện việc truy cập hàng triệu lần vào một cột trong một mẫu tin reader Mặc dù việc đọc một cột hàng triệu lần là hiếm, nhưng trong một số trường hợp, bạn nên tối ưu hóa mã của mình để cải thiện hiệu suất.

Khi truy cập dữ liệu, việc sử dụng số thứ tự chỉ mất 0.09 giây cho một triệu lần, trong khi sử dụng chuỗi kí tự lại tốn tới 0.63 giây Sự chậm trễ này xảy ra do cần dò tìm trong schema để lấy số thứ tự của cột trước khi truy xuất cơ sở dữ liệu Hiểu rõ thông tin này giúp bạn viết mã truy xuất dữ liệu hiệu quả hơn.

Vì vậy việc dùng chỉ số cột là cách dùng tốt nhất

OleDbDataReader cung cấp một bộ phương thức type-safe để đọc các cột dữ liệu, cho phép truy cập hầu hết các loại dữ liệu như GetInt32, GetFloat, và GetGuid.

Thí nghiệm của tôi cho thấy việc sử dụng GetInt32 chỉ mất 0.06 giây, nhanh hơn so với việc sử dụng chỉ số cột, vì phương pháp này yêu cầu thao tác ép kiểu để chuyển đổi về kiểu integer Do đó, nếu bạn đã biết trước schema, nên ưu tiên sử dụng các chỉ số thay vì tên cột.

Để duy trì sự cân bằng giữa tính dễ bảo trì và tốc độ, bạn cần định nghĩa các hằng số cho mỗi cột mà bạn sẽ truy cập nếu muốn sử dụng các chỉ mục.

MANAGING DATA VÀ RELATIONSHIPS: THE DATASET

Mục tiêu: Mô tả và lập trình CSDL với lớp DataSet

Lớp DataSet được thiết kế như một thùng chứa dữ liệu không liên kết, không có khái niệm về kết nối giữa các dữ liệu Dữ liệu trong lớp này được lưu trữ một cách độc lập và không có mối quan hệ trực tiếp với nhau.

DataSet không phân biệt nguồn gốc của cơ sở dữ liệu; nó có thể là các mẫu tin trong file CSV hoặc dữ liệu thu thập từ thiết bị đo lường.

Một DataSet bao gồm nhiều bảng dữ liệu, trong đó mỗi bảng chứa các cột và dòng dữ liệu Bạn có thể định nghĩa các liên kết giữa các DataSet, với mối quan hệ phổ biến là quan hệ cha-con Ví dụ, một mẫu tin trong bảng Order có thể liên kết với nhiều mẫu tin trong bảng Order_Details Quan hệ này có thể được xác định và đánh dấu trong DataSet.

Phần dưới đây giải thích các lớp được dùng trong một DataSet

Một data table tương tự như một bảng trong cơ sở dữ liệu vật lý, bao gồm nhiều cột với các thuộc tính riêng biệt và có thể chứa một hoặc nhiều dòng dữ liệu Data table có thể định nghĩa một khóa chính, bao gồm một hoặc nhiều cột, và cũng có thể bao gồm các ràng buộc cho các cột Tất cả thông tin này được thể hiện trong schema.

Có nhiều cách để định nghĩa schema cho một bảng dữ liệu cụ thể Nội dung này sẽ được thảo luận chi tiết sau phần giới thiệu về các cột và dòng dữ liệu.

Sơ đồ dưới đây chỉ ra một vài đối tượng có thể truy cập thông qua một bảng dữ liệu:

Hình 8.6 Một vài đối tượng

Một đối tượng DataTable và DataColumn có thể có các mở rộng riêng liên quan đến thuộc tính của chúng, với thông tin do người dùng xác định gắn liền Ví dụ, một cột có thể cung cấp mặt nạ nhập liệu để giới hạn các giá trị hợp lệ, như trong trường hợp số phúc lợi xã hội.

Các thuộc tính mở rộng đóng vai trò quan trọng khi dữ liệu được cấu trúc ở tầng giữa và được trả về cho client trong các tiến trình khác nhau Việc lưu trữ các chuẩn hợp lệ, như giá trị tối thiểu và tối đa cho các cột số, là cần thiết để đảm bảo tính chính xác và hợp lệ của dữ liệu.

Khi một bảng dữ liệu được tạo ra, nó có thể xuất phát từ việc chọn dữ liệu từ cơ sở dữ liệu, đọc từ file hoặc truy xuất thủ công trong mã Tập hợp Rows được sử dụng để chứa các giá trị trả về.

Tập hợp Columns bao gồm các đối tượng DataColumn có thể được thêm vào bảng, định nghĩa schema của dữ liệu như kiểu dữ liệu, tính khả rỗng và giá trị mặc định Bên cạnh đó, tập Constraints cho phép tạo ra các ràng buộc khóa chính hoặc tính độc nhất.

Sơ đồ của bảng dữ liệu có thể được sử dụng để biểu diễn trong DataGrid, điều này sẽ được thảo luận chi tiết trong chương sau Điều khiển DataGrid áp dụng các thuộc tính như kiểu dữ liệu của cột để xác định loại điều khiển phù hợp cho từng cột Chẳng hạn, một trường bit trong cơ sở dữ liệu có thể hiển thị dưới dạng checkbox trong DataGrid Nếu một cột được định nghĩa là NOT NULL trong sơ đồ dữ liệu, lựa chọn này sẽ được lưu trữ trong DataColumn và sẽ được kiểm tra khi người dùng cố gắng di chuyển khỏi dòng hiện tại.

Đối tượng DataColumn xác định các thuộc tính của một cột trong DataTable, bao gồm kiểu dữ liệu, tính chất chỉ đọc và các điều kiện khác Cột có thể được tạo ra thông qua mã lập trình hoặc tự động trong quá trình chạy ứng dụng.

Khi tạo cột, việc đặt tên cho nó là rất quan trọng; nếu không, hệ thống sẽ tự động gán tên theo định dạng Columnn, với n là số tự động tăng dần.

Kiểu dữ liệu của một cột có thể được thiết lập thông qua cấu trúc hoặc thuộc tính DataType Sau khi dữ liệu đã được tải vào bảng, bạn không thể thay đổi kiểu dữ liệu của cột, nếu không sẽ gặp phải ngoại lệ.

Các cột dữ liệu có thể được tạo để giữ các kiểu dữ liệu của NET Framework sau:

Bảng 8.4 Các kiểu dữ liệu của NET Framework

Sau khi tạo đối tượng DataColumn, bước tiếp theo là thiết lập các thuộc tính như tính khả rỗng (nullability) và giá trị mặc định Đoạn mã dưới đây minh họa một số tùy chọn có thể được cài đặt cho DataColumn.

DataColumn customerID = new DataColumn("CustomerID" , typeof(int)); customerID.AllowDBNull = false; customerID.ReadOnly = false; customerID.AutoIncrement = true; customerID.AutoIncrementSeed = 1000;

DataColumn name = new DataColumn("Name" , typeof(string)); name.AllowDBNull = false; name.Unique = true;

Các thuộc tính sau có thể được cài đặt trong một DataColumn:

AllowDBNull Nếu là true, cho phép cột có thể chấp nhận DBNull

AutoIncrement Cho biết rằng dữ liệu của cột này là một số tự động tăng AutoIncrementSeed Giá trị khởi đầu cho một cột AutoIncrement

AutoIncrementStep xác định bước tăng giữa các giá trị tự động, với giá trị mặc định là 1 Caption được sử dụng để hiển thị tên của cột trên giao diện ColumnMapping mô tả cách một cột được ánh xạ sang định dạng XML khi một DataSet được lưu thông qua phương thức DataSet.WriteXml.

ColumnName Tên của cột Nó tự động tạo ra trong thời gian chạy nếu không được cài đặt trong cấu trúc

DataType Kiểu giá trị của cột

DefaultValue Dùng để định nghĩa giá trị mặc định cho một cột

Expression Thuộc tính này định nghĩa một biểu thức dùng cho việct tính toán trên cột này

Bảng 8.5 Các thuộc tính có thể được cài đặt trong một DataColumn

CÁC SƠ ĐỒ XML

Mục tiêu: Vận dung XML để lập trình với CSDL

XML là định dạng chủ yếu cho việc truyền dữ liệu trong ADO.NET, tạo ra một cấu trúc vững chắc Với NET runtime, bạn có thể mô tả một DataTable trong file sơ đồ XML Ngoài ra, bạn có khả năng định nghĩa một DataSet, bao gồm nhiều DataTables và các mối quan hệ giữa chúng, kèm theo chi tiết và mô tả đầy đủ về dữ liệu.

Khi sở hữu một file XSD, bạn có thể sử dụng công cụ trong thời gian chạy để chuyển đổi sơ đồ này thành các lớp dữ liệu tương ứng, như lớp DataTable Bài viết này sẽ giới thiệu một file XSD đơn giản để mô tả thông tin sản phẩm, từ đó phát triển một số tính năng mở rộng.

The XML schema defined under the namespace "http://tempuri.org/XMLSchema1.xsd" specifies the structure for the "Products" element, ensuring that all elements are qualified This schema utilizes various XML namespaces, including those for standard XML data types and Microsoft data schemas, to ensure compatibility and proper data handling.

Trong chương 11, chúng ta sẽ xem xét kỹ lưỡng, nhưng hiện tại, tài liệu này chủ yếu định nghĩa một sơ đồ với các thuộc tính id cho sản phẩm Một kiểu phức tạp mang tên Product đã được định nghĩa để chứa nhiều yếu tố cho mỗi trường trong bảng Products.

Cảm ơn NET Framework đã công cụ XSD.EXE để tạo ra tất cả các mã cho các lớp này chỉ cần một file nhập XSD

Bạn có thể lưu file trên với tên Product.xsd, và chuyển nó thành mã với lệnh sau: xsd Product.xsd /d

Nó sẽ tạo ra file Product.cs

Có một vài cách có thể dùng XSD để thay đổi output generated Một vài cách phổ biến được đưa ra trong bảng sau.

/dataset (/d) Các lớp được thừa kế từ DataSet, DataTable, và

/language: Cho phép bạn chon ngôn ngữ để chuyển C# là giá trị mặc định, nhưng có thể chọn VB cho một file Visual Basic NET

/namespace: Định nghĩa không gian tên của code được phát ra Giá trị mặc định là no namespace

Bảng 8.10 Một vài cách phổ biến

Dưới đây là phiên bản rút gọn của XSD cho sơ đồ Products, đã loại bỏ các mã không cần thiết và chỉ giữ lại những phần quan trọng nhất Để xem kết quả cuối cùng, hãy chạy XSD.EXE trên sơ đồ Products và kiểm tra file cs được tạo ra Mã ví dụ có thể tìm thấy trong thư mục 10_XSD_DataSet.

// This code was generated by a tool

// Changes to this file may cause incorrect behavior and will be lost if

// This source code was auto-generated by xsd, Version=1.0.3512.0

// using System; using System.Data; using System.Xml; using System.Runtime.Serialization;

[System.ComponentModel.ToolboxItem(true)] public class Products : DataSet

{ private ProductDataTable tableProduct; public Products() public ProductDataTable Product public override DataSet Clone() public delegate void ProductRowChangeEventHandler ( object sender,

[System.Diagnostics.DebuggerStepThrough()] public class ProductDataTable : DataTable, System.Collections.IEnumerable

[System.Diagnostics.DebuggerStepThrough()] public class ProductRow : DataRow

Trong bài viết này, tôi đã chia mã thành ba phần và loại bỏ các thành phần protected và private, nhằm tập trung vào các giao diện chính Chúng ta sẽ phân tích mã trong phần liên quan đến DataSet.

Cấu trúc của Products() sử dụng phương thức tĩnh InitClass() để tạo một thể hiện của lớp ProductDataTable, kế thừa từ lớp DataTable, và thêm nó vào tập hợp các Tables của DataSet Bảng dữ liệu Products có thể được truy cập thông qua mã được cung cấp dưới đây.

DataTable products = ds.Tables["Products"];

Hoặc, đơn giản hơn bằng cách sử dụng thuộc tính Product, sẵn có trong các đối tượng xuất phát từ DataSet:

Lớp ProductDataTable bao gồm các mã khác như sau:

[System.Diagnostics.DebuggerStepThrough()] public class ProductDataTable :DataTable,

System.Collections.IEnumerable { private DataColumn columnProductID; private DataColumn columnProductName; private DataColumn columnSupplierID; private DataColumn columnCategoryID; private DataColumn columnQuantityPerUnit;

196 private DataColumn columnUnitPrice; private DataColumn columnUnitsInStock; private DataColumn columnUnitsOnOrder; private DataColumn columnReorderLevel; private DataColumn columnDiscontinued; internal ProductDataTable() : base("Product") { this.InitClass();

Lớp ProductDataTable kế thừa từ DataTable và triển khai giao diện IEnumerable, định nghĩa các cột trong bảng thông qua một thể hiện DataColumn tĩnh Các cột này được khởi tạo thông qua phương thức tĩnh InitClass() trong cấu tử Mỗi cột cung cấp một con trỏ nội, và lớp DataRow sẽ được mô tả chi tiết trong phần tiếp theo.

[System.ComponentModel.Browsable(false)] public int Count

{ get { return this.Rows.Count; }

// Other row accessors removed for clarity - there is one for each of the columns

Phương thức AddProductRow() có hai quá tải để thêm dòng vào bảng Quá tải đầu tiên tạo ra một DataRow mà không trả về giá trị, trong khi quá tải thứ hai nhận một tập hợp các giá trị cho các cột trong DataTable, tạo ra các giá trị cho một dòng mới, thêm dòng đó vào DataTable và trả lại dòng cho trình gọi.

} public ProductRow AddProductRow ( string ProductName , int SupplierID, int CategoryID , string QuantityPerUnit, System.Decimal UnitPrice , short UnitsInStock , short UnitsOnOrder , short ReorderLevel , bool Discontinued )

{ ProductRow rowProductRow = ((ProductRow)(this.NewRow())); rowProductRow.ItemArray = new object[]

197 null, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued }; this.Rows.Add(rowProductRow); return rowProductRow;

Hàm InitClass() trong lớp ProductDataTable tương tự như trong lớp DataSet, có chức năng thêm các cột vào DataTable Mỗi thuộc tính của cột được thiết lập một cách chính xác, sau đó cột sẽ được đưa vào tập hợp columns.

{ this.columnProductID = new DataColumn ( "ProductID", typeof(int), null, System.Data.MappingType.Element); this.Columns.Add(this.columnProductID);

// Other columns removed for clarity this.columnProductID.AutoIncrement = true; this.columnProductID.AllowDBNull = false; this.columnProductID.ReadOnly = true; this.columnProductName.AllowDBNull = false; this.columnDiscontinued.AllowDBNull = false;

Phương thức NewRowFromBuilder() được gọi từ NewRow() của DataTable, cho phép tạo một dòng định kiểu mạnh DataRowBuilder, được tạo bởi DataTable, chỉ có thể truy cập trong nhị phân System.Data Phương thức này được định nghĩa như sau: protected override DataRow NewRowFromBuilder(DataRowBuilder builder) { return new ProductRow(builder); }

Lớp cuối cùng, ProductRow, được phát triển từ DataRow, cung cấp phương thức truy cập bảo vệ kiểu cho tất cả các trường dữ liệu trong bảng Lớp này đại diện cho một dòng riêng lẻ và cung cấp các thành phần có khả năng đọc và ghi cho các cột trong bảng dữ liệu.

Các vùng khả rỗng sẽ được kiểm tra kĩ lưỡng Ví dụ dưới đây chỉ ra các khả năng của cột SupplierID:

[System.Diagnostics.DebuggerStepThrough()] public class ProductRow : DataRow

{ private ProductDataTable tableProduct; internal ProductRow(DataRowBuilder rb) : base(rb)

{ this.tableProduct = ((ProductDataTable)(this.Table));

{ get { return ((int)(this[this.tableProduct.ProductIDColumn])); } set { this[this.tableProduct.ProductIDColumn] = value; }

// Other column accessors/mutators removed for clarity public bool IsSupplierIDNull()

{ return this.IsNull(this.tableProduct.SupplierIDColumn);

{ this[this.tableProduct.SupplierIDColumn] = System.Convert.DBNull;

We can now integrate classes generated by XSD.EXE into our source code The following code utilizes these classes to retrieve data from the Products table and display it on the console: using System; using System.Data; using System.Data.SqlClient; public class XSD_DataSet.

199 string source = "server=(local)\\NetSDK;" +

"database=northwind"; string select = "SELECT * FROM Products";

SqlConnection conn = new SqlConnection(source);

SqlDataAdapter da = new SqlDataAdapter(select , conn);

Products ds = new Products(); da.Fill(ds , "Product"); foreach(Products.ProductRow row in ds.Product )

Console.WriteLine("'{0}' from {1}" , row.ProductID , row.ProductName);

Mã này bao gồm một lớp Products được lấy từ DataSet, với dữ liệu được tạo và điền bởi trình cung cấp dữ liệu Để biên dịch ví dụ này, bạn cần sử dụng lệnh xsd product.xsd /d và csc /recurse:*.cs.

Dòng đầu tiên tạo file Products.cs từ sơ đồ Products.XSD, trong khi dòng thứ hai sử dụng tham số /recurse:*.cs để duyệt qua tất cả các file có đuôi cs và thêm chúng vào nhị phân cuối cùng.

TẠO MỘT DATASET

Mục tiêu: Lập trình lấy dữ liệu XML đưa vào CSDL

Đầu tiên, hãy định nghĩa sơ đồ của bộ dữ liệu bao gồm DataTable, DataColumn, và Constraint Sau khi hoàn tất, bạn nên tạo DataSet với một số thông tin bổ sung Có hai phương pháp chính để đọc dữ liệu từ nguồn bên ngoài và chèn vào DataSet.

 Dùng trình cung cấp dữ liệu

 Đọc XML vào trong DataSet

VIII.1.Tạo một DataSet dùng một DataAdapter Đoạn mã về dòng dữ liệu được giới thiệu trong lớp SqlDataAdapter, được trình bày như sau: string select = "SELECT ContactName,CompanyName FROM Customers"; SqlConnection conn = new SqlConnection(source);

SqlDataAdapter da = new SqlDataAdapter(select , conn);

DataSet ds = new DataSet(); da.Fill(ds , "Customers");

Hai dòng in đậm chỉ ra cách dùng của SqlDataAdapter – OleDbDataAdapter cũng có nhưng tính năng ảo giống như Sql equivalent

SqlDataAdapter và OleDbDataAdapter là hai lớp kế thừa từ một lớp cơ bản, không phải là một bộ giao diện, và đặc biệt không thuộc các lớp SqlClient hoặc OleDb Cấu trúc kế thừa của chúng được thể hiện rõ ràng.

When extracting data from a dataset, it's essential to utilize specific commands to select the desired information This can include a SELECT statement, a stored procedure, or OLE commands.

The DB provider utilizes a TableDirect command, exemplified by employing a built-in structure from SqlDataAdapter to pass a SELECT statement into a SqlCommand This command is executed by invoking the Fill() method on the adapter.

In the previous chapter, we discussed stored procedures for INSERT, UPDATE, and DELETE operations, but we did not cover a procedure for SELECTing data In this section, we will address this gap and demonstrate how to call a stored procedure using a SqlDataAdapter to populate a DataSet.

VIII.1.1.Sử dụng một Stored Procedure trong một DataAdapter

Trước tiên chúng ta cần định nghĩa một stored procedure và cài nó vào cơ sở dữ liệu database Stored procedure đẻ SELECT dữ liệu như sau:

CREATE PROCEDURE RegionSelect AS SET NOCOUNT OFF

This example is relatively simple and does not warrant the use of a stored procedure, as it consists of just a basic SQL statement You can execute this stored procedure using SQL Server Query Analyzer or by running the StoredProc.sql file to utilize this example.

Next, we need to define an SqlCommand to execute this stored procedure The code is straightforward and has mostly been presented in previous sections: private static SqlCommand GenerateSelectCommand(SqlConnection conn) {

SqlCommand aCommand = new SqlCommand("RegionSelect" , conn); aCommand.CommandType = CommandType.StoredProcedure; aCommand.UpdatedRowSource = UpdateRowSource.None; return aCommand;

Phương thức này phát ra SqlCommand để gọi thủ tục RegionSelect khi thực thi

Và cuối cùng là móc nói nó với một SqlDataAdapter thông qua lời gọi phương thức

// Create a data adapter to fill the DataSet

To populate the Region DataTable, I create a new SqlDataAdapter and utilize its SelectCommand property to execute a stored procedure The Fill() method is then called to retrieve and insert all rows into the DataTable.

VIII.1.2 Tạo một DataSet từ XML

Một DataSet không chỉ tạo sơ đồ và các bảng tương ứng mà còn có khả năng đọc và ghi dữ liệu XML giống như một file trên đĩa, một stream, hoặc một text reader Để tải XML vào DataSet, bạn chỉ cần sử dụng phương thức ReadXML(), ví dụ như mã dưới đây để đọc từ một file trên đĩa.

DataSet ds = new DataSet(); ds.ReadXml(".\\MyData.xml");

CÁC CỐ GẮNG THAY ĐỔI DATASET

Sau khi xử lý dữ liệu trong một DataSet, đôi khi cần thực hiện các thay đổi Một ví dụ thường gặp là việc chọn lọc dữ liệu từ cơ sở dữ liệu, hiển thị thông tin cho người dùng và sau đó cập nhật lại cơ sở dữ liệu.

IX.1.Cập nhật với các Data Adapter

A SqlDataAdapter can encompass a SelectCommand, an InsertCommand, an UpdateCommand, and a DeleteCommand As the names suggest, these objects are instances of SqlCommand (or OleDbCommand for OleDbDataAdapter), allowing these commands to be executed as SQL statements or stored procedures.

Trong ví dụ này, tôi đã khôi phục lại các mã stored procedure từ phần Calling Stored Procedures để chèn, cập nhật, và xóa các mẫu tin Region

IX.1.1 Chèn một dòng mới

Có hai phương pháp để thêm một dòng mới vào DataTable Phương pháp đầu tiên là sử dụng phương thức NewRow, cho phép tạo ra một dòng trống, sau đó bạn có thể xác định vị trí và thêm nó vào tập Rows.

DataRow r = ds.Tables["Region"].NewRow(); r["RegionID"]9; r["RegionDescription"]="North West"; ds.Tables["Region"].Rows.Add(r);

Cách thứ hai để thêm một dòng mới là truyền một mảng dữ liệu vào phương thức Rows.Add() giống như sau:

DataRow r = ds.Tables["Region"].Rows.Add

Mỗi dòng trong DataTable sẽ có trạng thái RowState được đặt là Added Ví dụ, khi các mẫu tin được thêm vào DataTable, trạng thái dòng sẽ hiển thị như sau: "New row pending inserting into database" Điều này cho thấy các dòng mới đang chờ được cập nhật vào cơ sở dữ liệu.

999 North West Added Để cập nhật cơ sở dữ liệu từ một DataAdapter, gọi phương thức Update() như sau đây: da.Update(ds , "Region");

202 Đối với một dòng mới trong DataTable, sẽ thực thi stored procedure và xuất ra các mẫu tìn trong DataTable một lần nữa

New row updated and new RegionID assigned by database

Dòng cuối của DataTable cho thấy rằng mặc dù tôi đã nhập RegionID là 999, nhưng sau khi thực hiện stored procedure RegionInsert, giá trị đã được thay đổi thành 5 Điều này chứng tỏ rằng cơ sở dữ liệu thường tự động tạo khóa chính cho bạn.

SqlCommand aCommand = new SqlCommand("RegionInsert" , conn); aCommand.CommandType = CommandType.StoredProcedure; aCommand.Parameters.Add(new SqlParameter("@RegionDescription" ,

SqlDbType.NChar , 50, "RegionDescription")); aCommand.Parameters.Add(new SqlParameter("@RegionID" ,

SqlDbType.Int, 0, ParameterDirection.Output , false, 0, 0, "RegionID" , // Defines the SOURCE column

DataRowVersion.Default, null)); aCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;

When a data adapter executes commands, the output parameters are mapped back to the source code of the line A stored procedure includes an output parameter that is linked to a DataRow.

Giá trị của UpdateRowSource được cho trong bảng sau:

A stored procedure can return multiple output parameters and may also include a database of updated records.

The FirstReturnedRecord function returns a single data sample, which can be merged into the source DataRow This is particularly useful for tables with columns that have default or computed values, as it ensures synchronization with DataRows on the client side after an INSERT statement For example, one might use 'INSERT (columns) INTO (table) WITH (primarykey)', followed by 'SELECT (columns) FROM (table) WHERE (primarykey)' The returned samples can then be integrated into the set of rows.

None Tất cả dữ liệu trả về từ câu lệnh đều bị vứt bỏ

OutputParameters Bất kì tham số xuât nào của câu lệnh đều được ánh xạ vào một cột thích hợp trong DataRow

Bảng 8.11 Giá trị của UpdateRowSource

IX.1.2 Cập nhật một dòng đã có

Cập nhật một dòng trong DataTable sử dụng bộ chỉ mục của lớp DataRow với tên cột hoặc số thứ tự cột, như ví dụ dưới đây:

203 r["RegionDescription"]="North West England"; r[1] = "North East England";

Các hai câu lệnh đều cho cùng kết quả:

Trong quá trính cập nhật cơ sở dữ liệu, trạng của dòng được cập nhật sẽ được gán là Modified

Xóa một dòng là kết quả của việc gọi phương thức Delete(): r.Delete();

Khi một dòng được xóa, trạng thái của nó sẽ là Deleted và các cột trong dòng đó không còn giá trị, vì vậy bạn không thể đọc chúng Khi gọi phương thức Update(), tất cả các dòng đã bị xóa sẽ sử dụng DeleteCommand, dẫn đến việc thực thi stored procedure RegionDelete.

DataSet cung cấp khả năng mạnh mẽ để định nghĩa sơ đồ thông qua XML, cho phép bạn đọc và ghi dữ liệu từ và vào tài liệu XML một cách dễ dàng.

Phương thức DataSet.WriteXml() cho phép xuất dữ liệu từ DataSet với tùy chọn xuất chỉ dữ liệu hoặc cả dữ liệu và sơ đồ Ví dụ, bạn có thể sử dụng ds.WriteXml(".\\WithoutSchema.xml") để xuất chỉ dữ liệu, hoặc ds.WriteXml(".\\WithSchema.xml", XmlWriteMode.WriteSchema) để xuất cả dữ liệu và sơ đồ.

File đầu tiên, WithoutSchema.xml được đưa ra dưới đây:

File WithSchema.xml bao gồm cả sơ đồ và dữ liệu của DataSet:

Note that the extended properties for columns in a DataSet, such as AutoIncrement and AutoIncrementSeed, correspond to the properties that can be defined in a DataColumn.

LÀM VIỆC VỚI ADO.NET làm việc với ADO.NET

Mục tiêu: Vận dụng ADO.NET để lập trình CSDL

Phần cuối cùng này sẽ cố gắng đưa ra nhưng kịch bản phổ biến khi phát triển các ứng dụng truy cập cơ sở dữ liệu với ADO.NET

X.1 Phân tầng các ứng dụng

Việc phát triển phần mềm tương tác với dữ liệu thường được thực hiện theo mô hình phân tầng, trong đó ứng dụng được chia thành nhiều lớp khác nhau Một ví dụ điển hình là mô hình dịch vụ dữ liệu phân tầng kết hợp với cơ sở dữ liệu phân tầng, giúp tối ưu hóa hiệu suất và quản lý dữ liệu hiệu quả hơn.

Một trong những thách thức của mô hình này là phân tách dữ liệu giữa các tầng và định dạng truyền tải giữa chúng ADO.NET đã khắc phục những vấn đề này và nhanh chóng cung cấp hỗ trợ cho cấu trúc này.

Sao chép và trộn dữ liệu

Thật khó để copy một DB recordset? Trong In NET thậy dễ dàng để sao chép một DataSet:

Nó tạo ra một bản sao của DataSet nguồn, bao gồm từng DataTable, DataColumn, DataRow và Relation, với tất cả dữ liệu và trạng thái từ file nguồn được sao chép nguyên vẹn Nếu bạn chỉ muốn sao chép cấu trúc của DataSet, bạn có thể thực hiện theo cách khác.

Nó chỉ sao chép tất cả các table, relation, vân vân Tất nhiên, DataTable sẽ rỗng

Một thực tế phổ biến khi viết các hệ thống phân tầng, dựa trên Win32 hoặc web, là có truyền dữ liệu giữa các lớp càng ít càng tốt

Phương thức GetChanges() trong DataSet giúp xử lý các yêu cầu cập nhật dữ liệu Phương thức này thực hiện nhiều tác vụ và trả về một DataSet chứa các dòng đã được cập nhật từ nguồn dữ liệu Ý tưởng chính là truyền dữ liệu giữa các tầng với việc chỉ truyền một tập nhỏ dữ liệu.

Ví dụ sau chỉ ra cách tạo một "changes" DataSet:

Phương thức GetChanges() có hai quá tải, trong đó một quá tải nhận giá trị của DataRowState và trả về các trạng thái tương ứng Phương thức này gọi GetChanges(Deleted | Modified | Added) và kiểm tra sự tồn tại của thay đổi thông qua HasChanges() Nếu không có thay đổi nào, nó sẽ trả về giá trị ngay lập tức.

Để sao chép DataSet, trước tiên cần tạo một DataSet mới với tùy chọn bỏ qua các ràng buộc (EnforceConstraints = false) Sau đó, từng dòng đã thay đổi sẽ được sao chép vào DataSet mới này.

Bạn có thể tạo một DataSet chỉ chứa các thay đổi, sau đó truyền dữ liệu này qua các tầng để xử lý Khi dữ liệu được cập nhật vào cơ sở dữ liệu, DataSet "changes" có thể trả về cho trình gọi, trong đó một số tham số xuất từ các stored procedure đã cập nhật trong các cột Những thay đổi này có thể được kết hợp vào bộ DataSet bằng cách sử dụng phương thức Merge().

X.2 Tạo khoá với SQL Server

Stored procedure RegionInsert đã tạo ra một giá trị khóa chính để chèn vào cơ sở dữ liệu, nhưng phương thức này còn đơn giản và không linh hoạt Để đáp ứng nhu cầu của ứng dụng thực tế, cần áp dụng các kỹ thuật tạo khóa nâng cao hơn Một trong những cách tiếp cận là định nghĩa một định dạng cột đơn giản và trả về giá trị tương ứng.

To retrieve identity values from a stored procedure, utilize the following procedure that interacts with the Categories table in the Northwind database Input this stored procedure into SQL Query Analyzer or execute the StoredProcs.sql file located in the 13_SQLServerKeys directory.

CREATE PROCEDURE CategoryInsert(@CategoryName NVARCHAR(15),

@Description NTEXT, @CategoryID INTEGER OUTPUT) AS SET NOCOUNT OFF

INSERT INTO Categories (CategoryName, Description)

The procedure inserts a new row into the Category table and returns the primary key to the caller You can test this procedure by entering the following SQL line into the Query Analyzer: DECLARE @CatID int;

EXECUTE CategoryInsert 'Pasties' , 'Heaven Sent Food' , @CatID OUTPUT;

Khi thực hiện một bó lệnh, hệ thống sẽ chèn một dòng mới vào bảng Categories và trả về nhận dạng của dòng mới đó để hiển thị cho người dùng.

Sau vài tháng sử dụng, người dùng có thể cần một sổ theo dõi đơn giản để báo cáo các cập nhật và sửa đổi trên tên danh mục Để thực hiện điều này, bạn sẽ định nghĩa một bảng để thể hiện các giá trị mới và cũ của danh mục.

Hình 8.11 Tạo mối quan hệ

The existing code in StoredProcs.sql includes an AuditID column defined as an IDENTITY Additionally, a pair of triggers is structured to report changes made to the CategoryName field.

INSERT INTO CategoryAudit(CategoryID , OldName , NewName )

SELECT old.CategoryID, old.CategoryName, new.CategoryName

WHERE old.CategoryID = new.CategoryID;

To manage data changes in Oracle, you must use stored procedures, as SQL Server does not support OLD and NEW row content Instead of inserting a trigger, SQL Server utilizes an in-memory set called Inserted for new rows, while Deleted holds the old rows for deletion and updates.

Trigger này nhận CategoryID cho các cột giả và lưu các giá trị cũ và mới của cột CategoryName

Khi bạn gọi một stored procedure để chèn một CategoryID mới, bạn sẽ nhận được một giá trị nhận dạng mới, không phải là giá trị của dòng được chèn vào bảng Categories mà là giá trị được tạo trong bảng CategoryAudit Để kiểm tra vấn đề này, hãy mở SQL Server Enterprise Manager và xem nội dung của bảng Categories.

Hình 8.12 Xem nội dung của bảng Categories

Bảng này liệt kê tất cả categories tôi có trong thể hiện của cơ sở dữ liệu

XÂY DỰNG ỨNG DỤNG TỔNG HỢP

- Phân tích và tổng hợp các bài toán thực tế

- Vận dụng ngôn ngữ lập trình C# để xây dựng một ứng dụng vào thực tế

- Gỡ rối các chương trình xây dựng bằng ngôn ngữ lập trình C#

Các vấn đề chính sẽ được đề cập

 Xây dựng các chương trình liên quan đến Cấu trúc dữ liệu

 Xây dựng các chương trình liên quan đến cơ sở dữ liệu về việc quản lý thông tin, CSDL

 Xây dựng các chương trình liên quan đến quản trị hệ thống mạng

 Xây dựng các chương trình liên quan đến đồ hoạ, xử lý ảnh, xử lý đa phương tiện

 Xây dựng các chương trình liên quan đến quản lý File

Sau khi học xong bài này, học viên có khả năng:

- Xác định yêu cầu của các ứng dụng;

- Phân tích bài toán thực tế;

- Xây dựng được các phần mềm ứng dụng dựa trên ngôn ngữ lập trình C#

- Tổ chức làm việc nhóm;

- Tự phát triển công nghệ lập trình;

- Thực hiện các thao tác an toàn với máy tính;

Bài 1: Xây dựng chương trình ứng dụng “Xổ số điện toán”

Yêu cầu: - Giao diện đẹp, dễ sử dụng

- Đảm bảo tính khách quan khi quay số

Có nhiều lựa chọn cho việc quay số, bao gồm quay từng giải với thời gian quy định cho mỗi số, hoặc quay một lần duy nhất Bên cạnh đó, cần lưu ý về giá vé, cơ cấu giải thưởng và trị giá của từng giải thưởng để người chơi có thể tham gia một cách hiệu quả.

Bài 2: Xây dựng chương trình ứng dụng “máy tính tay”

Yêu cầu: - Giao diện đẹp, dễ sử dụng

Ứng dụng máy tính cần thực hiện các chức năng tính toán cơ bản như cộng, trừ, nhân, chia, phần trăm, lũy thừa và chức năng nhớ Hãy tham khảo giao diện của ứng dụng máy tính trên Windows để thiết kế giao diện một cách hợp lý và thân thiện với người dùng.

Bài 3: Xây dựng chương trình ứng dụng “MiniWord” (phần mềm soạn thảo văn bản)

Yêu cầu: - Giao diện đẹp, dễ sử dụng

- Đảm bảo có thể sử dụng để soạn văn bản, gồm:

+ Hệ thống thanh công cụ

Bài 4: Xây dựng chương trình ứng dụng “Quản lý điểm”

Yêu cầu: - Giao diện đẹp, dễ sử dụng

- Cơ sở dữ liệu MS Access hoặc SQL server

- Đảm bảo các chức năng, gồm;

+ Lọc theo các điều kiện: sinh viên chưa thi, thi thiếu điểm…

+ Tìm kiếm theo mã sinh viên, tên sinh viên hoặc theo khoa, lớp.

YÊU CẦU VỀ ĐÁNH GIÁ HOÀN THÀNH MÔN HỌC/MÔ ĐUN

- Về kiến thức: Được đánh giá qua bài kiểm tra viết, trắc nghiệm đạt được các yêu cầu sau:

+ Cách thức lập trình trực quan

Để xây dựng các ứng dụng cơ bản trong lập trình trực quan, việc nắm bắt các khái niệm như câu lệnh, từ khóa, cú pháp, đối tượng và sự kiện là rất quan trọng Những yếu tố này giúp người lập trình hiểu rõ cách thức hoạt động của ngôn ngữ lập trình và tạo ra các ứng dụng hiệu quả.

+ Có khả năng phân tích và xây dựng ứng dụng cho hệ thống dựa trên các ngôn ngữ có khả năng lập trình có thể NET

- Về kỹ năng: Đánh giá kỹ năng thực hành của sinh viên trong bài thực hành Lập trình trực quan đạt được các yêu cầu sau:

+ Sử dụng thành thạo các công cụ lập trình của Microsoft (C# để lập trình trực quan

+ Thiết kế, lập trình được một ứng dụng thông dụng để phục vụ công việc quản trị mạng hoặc các ứng dụng thực tế

- Về thái độ: cẩn thận, tự giác, chính xác

- Thang điểm đánh giá trong mỗi bài tổng hợp: thang điểm 10

Tiêu chí đánh giá Hệ số

Bảng 9.1 tiêu chí đánh giá

-Hình thức kiểm tra hết môđun có thể chọn một trong các hình thức sau:

Đối với kiến thức, hình thức đánh giá bao gồm viết, vấn đáp và trắc nghiệm Về kỹ năng, việc đánh giá sẽ dựa trên khả năng thực hành của sinh viên, cụ thể là khả năng thiết kế và lập trình một ứng dụng.

+ Thái độ: có thái độ nghiêm túc trong thực hành, Cẩn thận, thao tác nhanh chuẩn xác, tự giác trong học tập

+ Kiến thức: không quá 150 phút + Kỹ năng: không quá 4 giờ

CÁC THUẬT NGỮ CHUYÊN MÔN

TT Thuật ngữ Giải thích

3 Accessibility Khả năng truy xuất

Giao diện lập trình ứng dụng

9 Application domain Miền ứng dụng

19 Cache Kho chứa (truy xuất nhanh)

20 Caching Cơ chế lưu giữ

24 CLR [Common Language Runtime] Bộ thực thi ngôn ngữ chung

39 Context-sensitive help Trợ giúp cảm-ngữ-cảnh

44 Data binding Kỹ thuật kết dữ liệu Database Cơ sở dữ liệu

45 Debug Gỡ rối DebuggerTrình gỡ rối

46 Default Mặc định Delegate Ủy nhiệm hàm

47 Deploy Triển khai Destructor Phương thức hủy

48 Device Thiết bị Derive Dẫn xuất

49 Data binding Kỹ thuật kết dữ liệu Database Cơ sở dữ liệu

51 Digital signature Chữ ký số

55 Distributed Có tính phân tán

70 Event hander Phương thức thụ lý sự kiện

71 Event log Nhật ký sự kiện

74 Exception hander Phương thức thụ lý biệt lệ

75 Expiration Sự hết hiệu lực

86 FTP [File Transfer Protocol] Giao thức truyền file

89 GAC [Global Assembly Cache] Kho chứa gói kết hợp toàn cục

90 GC [Garbage Collector] Bộ thu gom rác

91 Generalization Tính tổng quát hóa

93 Globalization Sự toàn cầu hóa

96 GUI [Graphical User Interface] Giao diện người dùng đồ họa

97 GUID [Globally Unique Identifier] Định danh duy nhất toàn cục

103 HTML [HyperText Markup Language] Ngôn ngữ đánh dấu siêu văn bản

Môi trường phát triển tích hợp

116 Input Đầu vào / Dữ liệu nhập

122 Interoperability Khả năng liên tác

123 IP [Internet Protocol] Giao thức Internet

125 JIT [just-in-time] Tức thời / Vừa đúng lúc

138 Localization Sự bản địa hóa

140 Logic Mã thi hành chức năng

146 Membership Tư cách thành viên

157 Multithreading Lập trình đa tiểu trình

163 Object-oriented programming Lập trình hướng đối tượng

164 Operating system Hệ điều hành

166 Output Xuất ra / Kết xuất

181 Pooling Cơ chế dự trữ

182 POP3 [Post Office Protocol 3] Giao thức nhận mail 3

199 RBS [Role-Based Security] Bảo mật dựa-trên-vai-trò

200 Record Bản ghi / Mẩu tin

203 Reflection Cơ chế phản chiếu

205 Regular expression Biểu thức chính quy

208 Remotable Khả truy xuất từ xa

210 Reusability Khả năng tái sử dụng

219 Serializable Khả tuần tự hóa

220 Serialization Sự tuần tự hóa

225 Shared Được chia sẻ / Dùng chung

227 SMTP [Simple Mail Transfer Protocol] Giao thức truyền mail đơn giản

228 SOAP [Simple Object Access Protocol] Giao thức truy xuất đối tượng đơn giản

231 SQL [Structured Query Language] Ngôn ngữ truy vấn có cấu trúc

234 State | Stateless Có trạng thái | Phi trạng thái

235 Statement Câu lệnh / Khai báo

237 Stored procedure Thủ tục tồn trữ

242 Strongly-named Được định tên mạnh

243 Strongly-typed Được định kiểu mạnh

246 Synchronization Sự đồng bộ hóa

249 System tray Khay hệ thống

254 Thread Tiểu trình / Mạch trình / Tuyến đoạn

255 Thread-safe An toàn về tiểu trình

262 Type-safe Antoàn về kiểu dữ liệu

263 Unmanaged Không được quản lý

265 URI [Uniform Resource Identifier] Bộ nhận dạng tài nguyên đồng dạng

266 URL [Uniform Resource Locator] Bộ định vị tài nguyên đồng dạng

269 Validation Sự xác nhận tính hợp lệ

276 Wildcard Ký tự đại diện

Ngôn ngữ mô tả dịch vụ Web

281 XML [Extensible Markup Language] Ngôn ngữ đánh dấu mở rộng

Bảng 9.2 Các thuật ngữ hay sử dụng

Ngày đăng: 17/12/2023, 10:18

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

TÀI LIỆU LIÊN QUAN