Giáo trình Lập trình Windows Forms với C#

pdf 181 trang Gia Huy 17/05/2022 4150
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình Windows Forms với C#", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfgiao_trinh_lap_trinh_windows_forms_voi_c.pdf

Nội dung text: Giáo trình Lập trình Windows Forms với C#

  1. BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC LẠC HỒNG GIÁO TRÌNH LẬP TRÌNH WINDOWS FORMS VỚI C#
  2. LỜI NÓI ĐẦU Giáo trình Lập trình Windows Forms với C#.NET sử dụng cho sinh viên ngành Công nghệ thông tin. Giáo trình giúp sinh viên có cái nhìn tổng quan về ứng dụng Windows Application trong bộ công cụ Visual Studio .NET của Microsoft. Ngoài ra giáo trình còn cung cấp những kiến thức về các điều khiển mà Windows Application hỗ trợ, đi kèm đó là các ví dụ đơn giản được mô tả cụ thể để sinh viên có thể đọc và hiểu một cách nhanh chóng nhất. Nội dung của giáo trình gồm 11 chương. Chương 1: Giới thiệu tổng quan về ngôn ngữ C#, Cấu trúc của một chương trình C#, các kiểu dữ liệu cơ bản, cấu trúc lặp và cấu trúc rẽ nhánh, lớp String và cách tạo thư viện DLL. Chương 2: Giới thiệu về ứng dụng Windows Form, tạo form với hình dạng khác nhau, các sự kiện và phương thức của form. Chương 3: Giới thiệu về cách sử dụng của các điều khiển thông thường như: Label, Button, Textbox, ComboBox, ListBox, CheckBox và RadioButton. Chương 4: Giới thiệu về cách sử dụng các điều khiển đặc biệt như: Tooltip, HelpProvider, ErrorProvider, ProgressBar, Timer, ListView, TreeView, DateTimePicker và MonthlyCalendar. Chương 5: Giới thiệu về cách sử dụng của các điều khiển tạo Menu như: MenuStrip, ContextMenuStrip. Cách sử dụng các điều khiển: ImageList, NotifyIcon, ToolStrip, StatusStrip. Chương 6: Giới thiệu về các điều khiển có thể chứa điều khiển khác như: Panel, GroupBox, FlowLayoutPanel, TableLayoutPanel, TabControl, SplitContainer. Chương 7: Giới thiệu về các sử dụng của các điểu khiển dạng hộp thoại: MessageBox, ColorDialog, FontDialog, OpenFileDialog, SaveFileDialog, FolderBrowseDialog. Chương 8: Giới thiệu về các điều khiển làm việc với in ấn:PageSetupDialog, PrintPreviewDialog, PrintPreviewControl, PrintDialog, PrintDocument. Chương 9: Giới thiệu về cách xây dựng và sử dụng UserControl. Chương 10: Giới thiệu về các lớp đối tượng làm việc với màn hình và hệ thống như: Lớp SystemInformation, lớp Screen, lớp Sendkeys, lớp PowerStatus, Lớp Application, lớp Clipboard, lớp Cursor. Chương 11: Bài tập tổng hợp kiến thức.
  3. MỤC LỤC Lời nói đầu Chương 1: Giới thiệu về C# 1 1.1. Giới thiệu về Microsoft .NET Framework 1 1.1.1. .NET Framwork là gì 1 1.1.2. Các thành phần của Microsoft .NET Framework 1 1.2. Tổng quan 2 1.3. Cấu trúc tổng quát của một chương trình C# 4 1.3.1. Soạn thào bằng Notepad 4 1.3.2. Soạn thảo bằng Microsoft Visual Studio 2010 5 1.4. Biến và kiểu dữ liệu 8 1.4.1. Biến 8 1.4.2. Kiểu dữ liệu 9 1.4.2.1. Kiếu giá trị 9 1.4.2.2. Kiểu tham chiếu 10 1.4.2.3. So sánh sự khác biệt giữa kiểu giá trị và kiểu tham chiếu 11 1.4.2.4. Chuyển kiểu dữ liệu 11 1.5. Câu lệnh phân nhánh 13 1.5.1. Câu lệnh if 13 1.5.2. Câu lệnh switch 13 1.6. Câu lệnh lặp 14 1.6.1. Lệnh lặp while 14 1.6.2. Lệnh lặp do/ while 15 1.6.3. Lệnh lặp for 15 1.6.4. Lệnh lặp foreach 16 1.7. Lớp String 17 1.7.1. Giới thiệu về chuỗi ký tự 17 1.7.2. Phương thức và thuộc tính lớp String 18 1.8. Mảng 31 1.8.1. Mảng một chiều 31 1.8.2. Mảng hai chiều 32 1.9. Tạo và sử dụng DLL trong C# 33 1.9.1. Ưu điểm và nhược điểm khi sử dụng DLL 33
  4. 1.9.2. Các bước để tạo tập tin DLL 34 1.9.3. Các bước để sử dụng tập tin DLL 36 1.10. Bài tập cuối chương 39 Chương 2: Giới thiệu về Windows Forms 40 2.1. Giới thiệu 40 2.1.1. Ứng dụng Windows Forms 40 2.1.2. Không gian tên (namespace) 44 2.1.3. Thanh công cụ (Toolbox) 46 2.1.4. Định dạng mã C# 48 2.2. Các loại Form 48 2.2.1. Thuộc tính Form 48 2.2.2. Các loại Form 53 2.2.3. Các hình dạng của Form 55 2.2.4. Biến cố của Form 57 2.2.5. Phương thức 60 2.3. Bài tập cuối chương 64 Chương 3: Các điều khiển thông thường 65 3.1. Điều khiển Label 66 3.2. Điều khiển Button 70 3.3. Điều khiển TextBox 73 3.4. Điều khiển ComboBox và ListBox 77 3.4.1. ListBox 78 3.4.2. ComboBox 82 3.4.3. Phương thức và sự kiện của ComboBox và ListBox 85 3.5. Điều khiển CheckBox và RadioButton 89 3.5.1. CheckBox 89 3.5.2. RadioButton 93 3.6. Bài tập cuối chương 97 Chương 4: Các điều khiển đặc biệt 102 4.1. Điều khiển Tooltip, HelpProvider, ErrorProvider 103 4.1.1. Điều khiển Tooltip 103 4.1.2. Điều khiển HelpProvider 107 4.1.3. Điều khiển ErrorProvider 110 4.2. Điều khiển ProgressBar và Timer 115 4.2.1. Điều khiển ProgressBar 115 4.2.2. Điều khiển Timer 116
  5. 4.3. Điều khiển ListView 120 4.4. Điều khiển TreeView 130 4.5. Điều khiển DateTimePicker, MonthCalendar 136 4.5.1. Điều khiển DateTimePicker 136 4.5.2. Điều khiển MonthCalendar 138 4.6. Bài tập cuối chương 142 Chương 5: Điều khiển dùng để xây dựng Menu 146 5.1. Điều khiển ImageList 146 5.2. Điều khiển MenuStrip 149 5.3. Điều khiển ContextMenuStrip 159 5.4. Điều khiển NotifyIcon 164 5.5. Điều khiển ToolStrip 167 5.5.1. Điều khiển chứa trong ToolStrip 170 5.5.2. ToolStripContainer 172 5.6. Điều khiển StatusStrip 178 5.7. Bài tập cuối chương 180 Chương 6: Điều khiển chứa các điều khiển khác 185 6.1. Điều khiển GroupBox 185 6.2. Điều khiển Panel 190 6.3. Điều khiển FlowLayoutPanel 191 6.4. Điều khiển TableLayoutPanel 197 6.5. Điều khiển TabControl 200 6.6. Điều khiển SplitContainer 211 6.7. Bài tập cuối chương 218 Chương 7: Điều khiển Dialog và phương thức Message 222 7.1. Lớp MessageBox 223 7.2. Điều khiển ColorDialog 228 7.3. Điều khiển FontDialog 231 7.4. Điều khiển OpenFileDialog 234 7.5. Điều khiển SaveFileDialog 238 7.6. Điều khiển FolderBrowserDialog 243 7.7. Bài tập cuối chương 248 Chương 8: Làm việc với điều khiển in ấn 253 8.1. Điều khiển PageSetupDialog 254 8.2. Điều khiển PrintPreviewDialog 258
  6. 8.3. Điều khiển PrintPreviewControl 261 8.4. Điều khiển PrintDialog 266 8.5. Điều khiển PrintDocument 273 Chương 9: Điều khiển người dùng tự tạo 9.1. User Control 280 9.2. Xây dựng User Control 280 9.2.1. Thêm mới User Control ngay trong dự án 280 9.2.2. Tạo lớp và khai báo thừa kế từ lớp Control 285 9.2.3. Tạo dự án mới bằng cách chọn loại dự án là Windows Control Library 288 9.3. Sử dụng User Control 291 9.4. Cách sử dụng những thư viện tạo sẵn để thiết kế giao diện 294 9.5. Bài tập cuối chương 294 Chương 10: Làm việc với màn hình và hệ thống 298 10.1. Lớp SystemInformation 298 10.2. Lớp Screen 301 10.3. Lớp SendKeys 304 10.4. Lớp PowerStatus 309 10.5. Lớp Application 310 10.6. Lớp Clipboard 312 10.7. Lớp Cursors 316 Chương 11: Bài tập tổng hợp 318 Tài liệu tham khảo 325
  7. CHƢƠNG 1: GIỚI THIỆU VỀ C# 1.1. Giới thiệu về Microsoft .NET Framework 1.1.1. .NET Framework là gì ? .NET Framework là nền tảng phát triển hoàn hảo của Microsoft, cung cấp cho lập trình viên các thư viện dùng chung hỗ trợ cho việc phát triển các kiểu ứng dụng khác nhau bao gồm:  Ứng dụng ASP.NET  Ứng dụng Windows Form  Web Services  Windows Services  Ứng dụng mạng và các ứng dụng điều khiển truy cập từ xa 1.1.2. Các thành phần của Microsoft .NET Framework .NET Framework gồm hai thành phần chính là: Common Language Runtime (CLR) và thư viện lớp.  CLR: là nền tảng của .NET Framework, giúp Microsoft có thể tích hợp nhiều ngôn ngữ lập trình khác nhau như: VB.NET, C#.NET, ASP.NET, vào bộ công cụ lập trình Visual Studio.NET. Đồng thời giúp các ứng dụng viết trên các ngôn ngữ này có thể chạy được chung trên nền tảng hệ điều hành Windows. Sở dĩ Microsoft có thể làm được điều này, bởi vì các ngôn ngữ lập trình đều được biên dịch ra một ngôn ngữ trung gian (Intermediate Language – IL) và sử dụng chung kiểu dữ liệu hệ thống (Common Type System). Sau đó CLR sử dụng một trình biên dịch gọi là Just-in-Time (JIT) Compiler chuyển các đoạn mã IL thành mã máy và thực thi. Ngoài ra CLR còn làm các thành phần khác như: - Garbage Collection (GC): Gọi là bộ phận thu gom rác; có chức năng tự động quản lí bộ nhớ. Tại một thời điểm nhất được định sẵn, GC sẽ tiến hành thực hiện việc thu hồi những vùng nhớ không còn được sử dụng. - Code Access Security (CAS): Cung cấp quyền hạn cho các chương trình, tùy thuộc vào các thiết lập bảo mật của máy. Chẳng hạn, thiết lập bảo mật của máy cho phép chương trình chạy trên đó được sửa hay tạo file mới, nhưng không cho phép nó xóa file. CAS sẽ chăm sóc các đoạn mã, không cho phép chúng làm trái với các qui định này. - Code Verification: Bộ phận chứng nhận đoạn mã. Bộ phận này đảm bảo cho việc chạy các đoạn mã là đúng đắn, và đảm bảo an toàn kiểu dữ liệu. 1
  8. ngăn chặn các đoạn mã hoạt động vượt quyền như truy nhập vào các vùng nhớ không được phép.  Thư viện lớp: là một tập hợp lớn các lớp được viết bởi Microsoft, những lớp này được xây dựng một cách trực quan và dễ sử dụng; cho phép lập trình viên thao tác rất nhiều các tác vụ sẵn có trong Windows. - Base class library: Đây là thư viện các lớp cơ bản nhất, được dùng trong khi lập trình hay bản thân những người xây dựng .NET Framework cũng phải dùng nó để xây dựng các lớp cao hơn. Một số thư viện lớp base class library như: String, Interger, Exception, - ADO.NET và XML: Bộ thư viện này gồm các lớp dùng để xử lý dữ liệu. ADO.NET thay thế ADO để trong việc thao tác với các dữ liệu thông thường. Các lớp đối tượng XML được cung cấp để xử lý các dữ liệu theo định dạng mới XML. Một số thư viện trong ADO.NET và XML như: sqlDataAdapter, SqlCommand, DataSet, - Windows Forms: Bộ thư viện về lập trình Windows Forms gồm các lớp đối tượng dành cho việc xây dựng các ứng dụng Windows cơ bản. Một số thư viện thường dùng như: Form, UserControl, TextBox, Label, Button, ComboBox, ListBox, ListView, TreeView, - Web Services: là các dịch vụ được cung cấp qua Web (hay Internet). Dịch vụ được coi là Web Service không nhắm vào người dùng mà nhằm vào người xây dựng phần mềm. Web Services có thể dùng để cung cấp các dữ liệu hay một chức năng tính toán. - ASP.NET: Ứng dụng Web xây dựng bằng ASP.NET tận dụng được toàn bộ khả năng của .NET Framework. ASP.Net cung cấp một bộ các Server Control để lập trình viên bắt sự kiện và xử lý dữ liệu của ứng dụng như đang làm việc với ứng dụng của Windows. Một số thư như: WebControl, HTML Control, 1.2. Tổng quan về C# Vào ngày 12/2/2002, Microsoft chính thức cho ra mắt Visual Studio 2002 cùng với bản .NET Framework 1.0. Với nền tảng .NET Framework thì các ứng dụng về Windows Form, web, đều có thể được xây dựng trên nền tảng .NET. Hai ngôn ngữ chính mà Microsoft sử dụng để phát triển các ứng dụng trên là C# và Visual Basic.NET. C# được phát triển bởi đội ngũ kỹ sư của Microsoft, trong đó hai người dẫn đầu là Anders Hejlsberg và Scott Wiltamult. Vì là ngôn ngữ ra đời sau các ngôn ngữ khác 2
  9. như: Java, C, C++, Perl, Visual Basic, do đó C# có những đặc điểm nổi trội và mạnh mẽ hơn nhưng không kém phần đơn giản.  Các đặc điểm của C#: Microsoft thêm vào những đặc điểm mới vào để C# dễ sử dụng hơn: - C# là ngôn ngữ đơn giản: Các cú pháp, biểu thức, toán tử đều giống với C, C++. Ngoài ra C# loại bỏ một số khái niệm phức tạp khó hiểu như: Con trỏ, Macro, đa kế thừa, template, lớp cơ sở ảo. - C# là ngôn ngữ hiện đại: Có tất cả các đặc tính của một ngôn ngữ hiện đại như: xử lý ngoại lệ, thu gom bộ nhớ tự động, kiểu dữ liệu mở rộng, và bảo mật mã nguồn. - C# là ngôn ngữ hướng đối tượng: Là một ngôn ngữ thuần hướng đối tượng, do đó chứa tất cả các đặc điểm để có thể lập trình theo hướng đối tượng: Sự đóng gói (Encapsulation), sự thừa kế (Inheritance), và sự đa hình (Polymorphism). - C# là ngôn ngữ mạnh mẽ và mềm dẻo: Có thể sử dụng cho những dự án khác nhau như: xử lý văn bản, ứng dụng đồ họa, bảng tính, - C# là ngôn ngữ có ít từ khóa: là ngôn ngữ sử dụng giới hạn các từ khóa, chỉ khoảng 80 từ khóa và hơn 10 kiểu dữ liệu được xây dựng sẵn như bảng 1.1. Bảng 1.1: Bảng mô tả các từ khóa của C# abstract default foreach object sizeof unsafe as delegate goto operator stackalloc ushort base do if out static using bool double implicit override string virtual break else in params struct volatile byte enum int private switch void case event interface protected this while catch explicit internal public throw decimal char extern is readonly true for checked false lock ref try null class finally long return typeof short const fixed namespace sbyte uint unchecked 3
  10. continue float new sealed ulong 1.3. Cấu trúc tổng quát của một chƣơng trình C# Các đoạn mã C# có thể được soạn thảo trong một trình soạn thảo văn bản bất kỳ, sau khi biên soạn xong cần lưu tập tin với đuôi .cs 1.3.1. Soạn thảo bằng Notepad Trong quá trình soạn thảo cần lưu ý C# là một ngôn ngữ thuần hướng đối tượng. Do đó tất cả đoạn mã của chương trình đều phải thuộc lớp. Ví dụ 1.1: Soạn thảo một chương trình C# in dòng chữ Hello World ra màn hình  Bước 1: Giải thích: - Ở đoạn chương trình trên, hàm Main được khai báo là static. Việc khai báo này cho biết hàm Main có thể được sử dụng mà không cần thông qua đối tượng - Hàm WriteLine nằm trong lớp Console, do đó nếu sử dụng phải khai báo thêm dòng lệnh “Using System;” phía trên cùng để việc gõ lệnh được nhanh chóng hơn như sau: “Console.WriteLine()”. Nếu không khai báo “Using System;” thì buộc phải viết đầy đủ cú pháp: “System.Console.WriteLine()”, với System là một namespace. - C# phân biệt chữ thường và chữ hoa, do đó lệnh writeline khác lệnh WriteLine.  Bước 2: Khi soạn thảo xong. Lưu tập tin với tên: ChaoMung.cs  Bước 3: Thực thi chương trình phải thực hiện hai bước: - Mở cửa sổ Command Line và biên dịch tập tin ChaoMung.cs vừa tạo ra sang mã máy (tạo ra file có đuôi .exe) như hình 1.1: Để biên dịch dùng trình biên dịch dòng lệnh C# (csc.exe) chương trình này được chép vào máy 4
  11. trong quá trình cài .NET Framework. Nếu cài Framwork 4.0 thì tiến hành vào đường dẫn: C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe Hình 1.1: Biên dịch tập tin hello.cs - Thực thi tập tin có đuôi .exe như hình 1.2: Hình 1.2: Thực thi tập tin Hello.exe 1.3.2. Soạn thảo bằng Microsoft Visual Studio 2010  Bước 1: Mở Microsoft Visual Studio 2010 và tạo 1 dự án mới như hình 1.3 5
  12. Bước 1: Chọn thực Bước 2: Chọn mục đơn File > New Project Hình 1.3: Tạo dự án mới  Bước 2: Tạo một loại dự án đơn giản là Console Application để minh họa bằng ngôn ngữ C# và đặt tên Baitap lưu ở ổ đĩa D như hình 1.4 Bước 1: Chọn loại dự án. Nếu lập trình môi trường Console thì chọn loại dự án là Console Application. Nếu lập trình môi trường Windows Forms thì chọn Windows Forms Application Hình 1.4: Tạo loại dự án và đặt tên cho dự án  Bước 3: Soạn thảo mã C# trong trình biên dịch như hình 1.5 6
  13. Hình 1.5: Giao diện soạn thảo mã lệnh  Bước 4: Biên dịch chương trình: trên thanh menu chọn Build > Build Solution như hình 1.6 hoặc ấn tổ hợp phím Ctrl + Shift + B. Hình 1.6: Biên dịch chương trình  Bước 5: Thực thi chương trình: trên thanh menu chọn Debug > Start Debugging như hình 1.7 hoặc phím F5. 7
  14. Hình 1.7: Thực thi chương trình 1.4. Biến và Kiểu dữ liệu 1.4.1. Biến Biến là nơi lưu trữ dữ liệu của chương trình. Dữ liệu của biến nằm trong bộ nhớ vật lý của Ram và có thể thay đổi được. Muốn sử dụng biến trước tiên lập trình phải chỉ định biến có một kiểu dữ liệu cụ thể nào đó.  Cú pháp khai báo biến: Lưu ý: Tên biến phải được đặt phù hợp với quy tắc đặt tên  Cú pháp khởi tạo giá trị cho biến: = Trong đó: = là phép toán gán giá trị Quy tắc đặt tên: Các tên biến, tên hằng, tên hàm, trong C# đề phải đặt tên đúng với quy tắc sau:  Một tên biến có thể bắt đầu bằng chữ hoa hay chữ thường. Tên có thể chứa ký tự hay số và ký tự gạch dưới (_).  Ký tự đầu tiên của biến phải là ký tự , không được là số.  Trong C# phân biệt hoa thường. 8
  15.  Các từ khóa không thể sử dụng để đặt tên cho biến. Nếu muốn dùng từ khóa đặt tên thì ta thêm ký tự @ phía trước. Ví dụ 1.2: Employee: Hợp lệ student: Hợp lệ _Name: Hợp lệ Emp_Name: Hợp lệ @goto: Hợp lệ static: Không hợp lệ, trùng từ khóa 4myclass: Không hợp lệ, không thể bắt đầu bằng ký tự số Student&Falculty: Không hợp lệ, không được chứa ký tự đặc biệt 1.4.2. Kiểu dữ liệu Cũng như ngôn ngữ lập trình C++ hay Java, C# chia thành hai tập kiểu dữ liệu chính:  Kiểu giá trị  Kiểu tham chiếu Mọi kiểu dữ liệu trong C# sẽ thuộc một trong hai kiểu giá trị hoặc kiểu tham chiếu. Kiểu giá trị thì lưu trong stack, còn kiểu tham chiếu lưu trong heap. Stack: một vùng bộ nhớ dành lưu trữ dữ liệu với chiều dài cố định. Ví dụ 1.3: số nguyên kiểu int luôn chiếm dụng 4 bytes. Mỗi chương trình khi thực thi đều được cấp riêng 1 stack mà các chương trình khác không truy cập tới được Heap: một vùng bộ nhớ dùng lưu trữ dữ liệu có dung lượng thay đổi. Ví dụ 1.4: như kiểu string, khi ta tạo đối tượng thuộc lớp string, thì đối tượng sẽ được xác định bởi hai thành phần: Địa chị đối tượng lưu ở stack, còn giá trị đối tượng thì sẽ lưu ở heap. 1.4.2.1. Kiểu giá trị Kiểu giá trị thường là các kiểu do C# định nghĩa sẵn bao gồm: double, char, int, float, enum, struct, . Biến của kiểu giá trị lưu trữ một giá trị thực, giá trị này được lưu trữ trong stack, không thể mang giá trị null và phải chứa giá trị xác định. Bảng 1.2: Bảng mô tả các kiểu dữ liệu giá trị trong C# Kiểu C# Số Byte Kiểu .NET Mô tả byte 1 Byte Số nguyên dương không dấu: 0 đến 255 char 2 Char Ký tự Unicode bool 1 Boolean Giá trị logic true/ false sbyte 1 Sbyte Số nguyên có dấu: -128 đến 127 short 2 Int16 Số nguyên có dấu: -32.768 đến 32.767 9
  16. ushort 2 Uint16 Số nguyên không dấu: 0 đến 65.535 int 4 Int32 Số nguyên có dấu: -2.147.483.647 đến 2.147.483.647 uint 4 Uint32 Số nguyên không dấu: 0 đến 4.294.967.295 float 4 Single Kiểu dấu chấm động, giá trị xấp xỉ từ 3,4E-38 đến 3,4E+38; với 7 chữ số có nghĩa double 8 Double Kiểu dấu chấm động, giá trị xấp xỉ từ 1,7E-308 đến 1,7E+308; với 15, 16 chữ số có nghĩa decimal 8 Decimal Có độ chính xác đến 28 con số và giá trị thập phân, được dùng trong tính toán tài chính, kiểu này đòi hỏi phải có hậu tố “m” hay “M” theo sau giá trị long 8 Int64 Kiểu số nguyên có dấu có giá trị trong khoảng: -9.233.370.036.854.775.808 đến - 9.233.372.036.854.775.807 ulong 8 Uint64 Số nguyên không dấu từ 0 đến 0xfffffffffffffff Lưu ý: Kiểu số thực: Trình biên dịch luôn hiểu bất cứ một số thực nào cũng là một số kiểu double trừ khi khai báo rõ ràng, do đó để gán một số kiểu float thì số phải có ký tự f theo sau. ví dụ 1.5: float a=0.15f; Kiểu giá trị bool trong C# nhất thiết phải là true hoặc false. 1.4.2.2. Kiểu tham chiếu Biến có kiểu dữ liệu tham chiếu lưu trữ địa chỉ của biến khác trên bộ nhớ heap. Như vậy các lớp đối tượng String, Object, đều được hiểu như kiểu dữ liệu tham chiếu. Ngoài ra các kiểu dữ liệu do người dùng xây dựng nên cũng được gọi là kiểu tham chiếu. Ví dụ 1.6: string str = “A”; Stack Heap @ “A” Địa chỉ biến str Giá trị của biến str 10
  17. 1.4.2.3. Bảng so sánh sự khác biệt giữa kiểu giá trị và kiểu tham chiếu Bảng 1.3: Bảng so sánh sự khác biệt giữa kiểu giá trị và kiểu tham chiếu Kiểu giá trị Kiểu tham chiếu Biến lưu trữ Giá trị của biến Địa chỉ của biến Vị trí lưu trữ giá trị Stack Heap Giá trị mặc định 0 Null Phép toán gán Sao chép giá trị Sao chép địa chỉ 1.4.2.4. Chuyển kiểu dữ liệu Việc chuyển đổi kiểu dữ liệu trong C# có thể thực hiện bằng một trong các cách sau:  Sử dụng lớp Convert: Đây là một lớp được C# xây dựng sẵn phục vụ cho việc chuyển đổi từ kiểu dữ liệu này sang kiểu dữ liệu khác. Các phương thức trong lớp Convert phần lớn đều là phương thức tĩnh: - ToInt32( ) - ToInt64( ) - ToString( ) - ToDouble( ) - ToBoolean( ) - ToByte( ) - : có thể là chuỗi ký tự, hằng số, biến số nguyên, số thực hoặc kiểu bool. Nếu trong quá trình chuyển kiểu đặt tham số là null thì hàm Convert sẽ trả về giá trị mặc định. Ví dụ 1.7: int a = Convert.ToInt32("10"); //chuyển chuỗi 10 sang số nguyên bool b = Convert.ToBoolean(27); //chuyển số 27 sang kiểu boolean bool a = Convert.ToBoolean("hello"); //Sai định dạng, không chuyển được int b = Convert.ToInt32("123456787654"); //Tràn bộ nhớ, không chuyển được double d = Convert.ToDouble(null); //Trả về giá trị mặc định  Sử dụng phương thức Parse: Phương thức Parse thường được sử dụng để chuyển đổi chuỗi sang một kiểu dữ liệu cụ thể nào đó. Mỗi kiểu dữ liệu xây dựng sẵn trong C# đều có hỗ trợ phương thức Parse để chuyển đổi chuỗi sang kiểu dữ liệu tương ứng: 11
  18. - Double.Parse( ): Chuyển chuỗi về kiểu Double - Int32.Parse( ): Chuyển chuỗi về kiểu Int32 - Int64.Parse( ): Chuyển chuỗi về kiểu Int64 - Boolean.Parse( ): Chuyển chuỗi về kiểu Boolean - Single.Parse( ): Chuyển chuỗi về kiểu Single - Ví dụ 1.8: int a = Int32.Parse("123"); //a sẽ mang giá trị 123  float b = Float.Parse("20.7"); //b sẽ mang giá trị 20.7  bool c = Boolean.Parse("true"); //c sẽ mang giá trị true int a = Int32.Parse(“Hello”); //sai định dạng, không chuyển được byte b = Byte.Parse(“10000000000”); //quá giới hạn, không chuyển được bool c = Boolean.Parse(null); //tham số là null, không chuyển được  Sử dụng phương thức TryParse: Phương thức TryParse cũng được sử dụng để chuyển đổi chuỗi sang một kiểu dữ liệu cụ thể như Parse. Các kiểu dữ liệu xây dựng sẵn trong C# đều có phương thức TryParse. Tuy nhiên, sự khác biệt của TryParse và Parse là: - Cú pháp sử dụng có sự khác biệt: Có hai tham số truyền vào TryParse; Tham số thứ nhất là chuỗi cần chuyển đổi và tham số thứ hai là biến chứa giá trị chuyển đổi (biến truyền vào phải truyền ở dạng tham chiếu) - Giá trị trả về của TryParse sẽ là true nếu chuyển kiểu thành công và trả về false nếu chuyển kiểu không thành công. Ví dụ 1.9: int a; Int32.TryParse(“123”, out a); //a sẽ mang giá trị 123 bool b; Boolean.TryParse(“false”, out b); //b sẽ mang giá trị false int a; Int32.TryParse("hello", out a); //trả về giá trị false, a mang giá trị 0 bool b; Boolean.TryParse("", out b); //trả về giá trị false, b mang giá trị false  Casting (ép kiểu): Đây là cách chuyển kiểu được sử dụng khi muốn chuyển đổi giữa những kiểu dữ liệu gần tương tự nhau. Thường áp dụng với kiểu số. 12
  19. Ví dụ 1.10: int x= 10; float y = x; //chuyển đổi ngầm định, y = 10 int z = (int)y; //chuyển đổi rõ ràng, z = 10 int x = 10; Trong quá trính chuyển kiểu có thể xảy ra lỗi do chuyển giữa các kiểu dữ liệu không tương thích: Kiểu chuỗi sang kiểu số, kiểu bool sang kiểu float, 1.5. Câu lệnh phân nhánh Việc phân nhánh có thể được tạo ra bằng các từ khóa: if, else, switch, case. Sự phân nhánh chỉ được thực hiện khi biểu thức điều kiện phân nhánh được xác định là đúng. 1.5.1. Câu lệnh if  Cú pháp: if (biểu thức điều kiện) [else ] Nếu các câu lệnh trong thân của if hay else mà lớn hơn một lệnh thì các lệnh này phải được bao trong một khối lệnh, tức là phải nằm trong dấu khối { }:  Cú pháp: if (biểu thức điều kiện) { ; ; . } [else { ; ; . }] 1.5.2. Câu lệnh switch Khi có quá nhiều điều kiện để chọn thực hiện thì dùng câu lệnh if sẽ rất rối rắm và dài dòng, Các ngôn ngữ lập trình cấp cao đều cung cấp một dạng câu lệnh switch liệt kê các giá trị và chỉ thực hiện các giá trị thích hợp. 13
  20.  Cú pháp: switch (biểu thức điều kiện) { case : [default: ] } Lưu ý: - : Là lệnh chỉ định việc kết thúc một case, lệnh nhảy trong switch là break hoặc goto; Trường hợp trong case không có lệnh nhảy thì trình biên dịch sẽ tuần tự thực hiện các câu lênh trong từng case của switch theo thứ tự từ trên xuống. - Trong trường hợp switch sử dụng nhiều case, có thể nhảy trực tiếp đến case cụ thể nào đó bằng goto; hoặc thoát khỏi switch sử dụng break. - : là hằng nguyên hoặc biến; Nếu là biến bắt buộc phải là biến kiểu số nguyên. 1.6. Câu lệnh lặp C# kế thừa cú pháp câu lệnh của C/C++:  Lệnh lặp while  Lệnh lặp do/ while  Lệnh lặp for Ngoài ra 3 lệnh lặp cơ bản trên, C# còn có thêm lệnh lặp foreach dùng để làm việc với mảng, tập hợp. C# cũng cung cấp các lệnh nhảy như: break, goto, continue và return sử dụng kết hợp với lệnh lặp 1.6.1. Lệnh lặp while Ý nghĩa của vòng lặp while là: “Trong khi điều kiện đúng thì thực hiện các công việc này”.  Cú pháp: while (Biểu thức) { } 14
  21. Biểu thức của vòng lặp while là điều kiện để các lệnh được thực hiện, biểu thức này bắt buộc phải trả về một giá trị kiểu bool là true/false Ví dụ 1.11: Viết chương trình tính tổng các số lẻ >0 và nhỏ hơn 10 static void Main(string[] args) { int i = 1, tong = 0; while (i }while ( điều kiện ); Sự khác biệt tối quan trọng của while và do while là tối thiểu sẽ có một lần các câu lệnh trong do while được thực hiện Ví dụ 1.12: Viết chương trình tính tổng các số lẻ >0 và nhỏ hơn 10 static void Main(string[] args) { int i = 1, tong = 0; do { tong = tong + i; i = i+2; }while(i<10); } 1.6.3. Lệnh lặp for Vòng lặp for bao gồm ba phần chính:  Khởi tạo biến đếm vòng lặp  Kiểm tra điều kiện biến đếm, nếu đúng thì sẽ thực hiện các lệnh bên trong vòng for 15
  22.  Thay đổi bước lặp.  Cú pháp: for ( [phần khởi tạo] ; [biểu thức điều kiện]; [bước lặp]) { } Ví dụ 1.13: Viết chương trình tính tổng các số lẻ >0 và nhỏ hơn 10 static void Main(string[] args) { int i, tong = 0; for(i=1; i in ) { } Do lặp dựa trên một mảng hay tập hợp nên toàn bộ vòng lặp sẽ duyệt qua tất cả các thành phần của tập hợp theo thứ tự được sắp. Khi duyệt đến phần tử cuối cùng trong tập hợp thì chương trình sẽ thoát ra khỏi vòng lặp foreach Ví dụ 1.14: Tính tổng các số lẻ trong mảng A = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} static void Main(string[] args) { int[] intArray = {0,1,2,3,4,5,6,7,8,9,10}, tong = 0; foreach( int item in intArray) { if (item % 2 != 0) tong = tong + item; } } 16
  23. 1.7. Lớp String 1.7.1. Giới thiệu về chuỗi ký tự C# xem những chuỗi như là những kiểu dữ liệu cơ bản , việc sử dụng chuỗi trong C# rất linh hoạt, mạnh mẽ, và quan trọng nhất là dễ sử dụng. Chỉ mục trong chuỗi được tính từ số 0. Để làm việc với chuỗi, C# cung cấp lớp System.String. Khi khai báo một chuỗi C# bằng cách dùng từ khóa string, đồng nghĩa với việc người dùng đã khai báo một đối tượng của lớp System.String. Ví dụ 1.15: string chuoi=“hello”; Ngoài việc, ta cũng có thể khởi tạo chuỗi từ 1 mảng char: Ví dụ 1.16: // Khởi tạo mảng ký tự char[] chars = {'c', 's', 'h', 'a', 'r', 'p'}; // Khởi tạo chuỗi từ mảng ký tự string str = new string(chars); Lưu ý:  Khi gán giá trị trong chuỗi có thể chứa ký tự escape: „\n‟, „\t‟, „\a‟, Ví dụ 1.17: string newString = “Day la chuoi \n trich dan”; Ký tự xuống hàng  Trong trường hợp muốn lưu đường dẫn thư mục vào một chuỗi: Ví dụ 1.18: string path = “ c:\baitap”; Trình biên dịch báo lỗi, vì không hiểu ký tự escape „\b‟  Do đó muốn trình biên dịch hiểu „\b‟ như những ký tự thông thường thì người dùng phải thêm một ký tự „\‟ phía trước: Ví dụ 1.19: string path = “ c:\\baitap”;  Ngoài việc sử dụng dấu \ để giữ nguyên các ký tự trong chuỗi ta cũng có thể khai báo chuỗi như là 1 chuỗi nguyên văn bằng cách thêm @ phía trước chuỗi. Ví dụ 1.20: string path = @“D:\soft\VMWare” 17
  24. 1.7.2. Phƣơng thức và thuộc tính lớp String Bảng 1.4: Bảng tổng hợp các phương thức lớp String System.String Phương thức/ Thuộc tính Ý nghĩa Empty Thuộc tính tĩnh; Thể hiện chuỗi rỗng Compare() Phương thức tĩnh; So sánh hai chuỗi CompareOrdinal() Phương thức tĩnh; So sánh hai chuỗi không quan tâm đến thứ tự Concat() Phương thức tĩnh; Tạo ra chuỗi mới từ một hay nhiều chuỗi khác Copy() Phương thức tĩnh; Tạo ra một chuỗi mới bằng cách sao chép từ chuỗi khác Equal() Phương thức tĩnh; Kiểm tra xem hai chuỗi có cùng giá trị hay không Insert() Trả về chuỗi mới đã được chèn một chuỗi xác định LastIndexOf() Chỉ ra vị trí xuất hiện cuối cùng của một chuỗi xác định trong chuỗi ban đầu PadLeft() Canh lề phải những ký tự trong chuỗi, chèn vào bên trái khoảng trắng hay các ký tự xác định PadRight() Canh lề trái những ký tự trong chuỗi, chèn vào bên phải khoảng trắng hay các ký tự xác định Remove() Xóa đi một số ký tự xác định Split() Trả về chuỗi được phân định bởi những ký tự xác định trong chuỗi StartWith() Xem chuỗi có bắt đầu bằng một số ký tự xác định hay không SubString() Lấy một chuỗi con ToCharArray() Sao chép những ký tự từ một chuỗi đến mảng ký tự 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ữ hoa Format() Phương thức tĩnh; Định dạng một chuỗi dùng ký tự lệnh định dạng xác định Join() Phương thức tĩnh; Kết nối các chuỗi xác định giữa mỗi thành phần của mảng chuỗi Length Trả về chiều dài của chuỗi CompareTo() So sánh hai chuỗi CopyTo() Sao chép một số các ký tự xác định đến một mảng ký tự Unicode EndsWith() Chỉ ra vị trí của chuỗi xác định phù hợp với chuỗi đưa ra Trim() Xóa bỏ tất cả sự xuất hiện của khoẳng trắng trong chuỗi TrimEnd() Xóa các khoảng trắng ở vị trí cuối TrimStart() Xóa các khoảng trắng ở vị trí đầu 18
  25.  Thuộc tính Empty: Đại diện cho 1 chuỗi rỗng. Sử dụng khi muốn khai báo 1 chuỗi là rỗng. Ví dụ 1.21: string chuoi = string.Empty; Khi ta khai báo như trên nghĩa là tương đương với khai báo: string chuoi = “”;  Thuộc tính Length: Dùng để xác định chiều dài của chuỗi. Ví dụ 1.22: static void Main(string[] args) { string str = "pham phuong nguyen"; int chieudai = str.Length; } //Kết quả: chieudai = 18  Nhóm các phƣơng thức so sánh chuỗi: Compare, CompareOrdinal, CompareTo, Equal - Phương thức Compare: Phương thức tĩnh so sánh hai chuỗi Cách sử dụng: int gt = String.Compare( , , [true]); . Nếu gt = 0: hai chuỗi bằng nhau . Nếu gt = 1: chuỗi 1 lớn hơn chuỗi 2 . Nếu gt = -1: chuỗi 1 nhỏ hơn chuỗi 2 . Nếu sử dụng phương thức không có tham số true, thì sẽ phân biệt chữ thường, chữ hoa. Nếu có tham số true thì sẽ không biệt chữ thường hay chữ hoa. Ví dụ 1.23: public static void Main(string []args) { int gt = String.Compare(“abDb”, “abdb”); //gt = 1 int gt1= String.Compare(“abDb”, “abdb”, true); //gt1 = 0 int gt2= String.Compare(“abdaF”, “abdb”); //gt2 = -1 } - Phương thức so sánh chuỗi CompareOrdinal: So sánh chuỗi trả về một giá trị kiểu int; Lần lượt tìm từ đầu chuỗi đến cuối chuỗi nếu thấy có ký tự khác biệt giữa hai chuỗi. Tính hiệu mã ASCII của hai ký tự này và trả kết quả vừa tính được. 19
  26. Cách sử dụng: int gt = String.CompareOrdinal( , ); Ví dụ 1.24: public static void Main(string []args) { int gt1 = String.CompareOrdinal(“abcd”, “aBcd”); //gt1=32 int gt2 = String.CompareOrdinal(“abcd”, “aBcdefg”); //gt2=32 int gt3 = String.CompareOrdinal(“Abcd”, “aBcdefg”); //gt3=-32 int gt4 = String.CompareOrdinal(“abcd”, “abcd”); //gt4=0 } - Phương thức so sánh chuỗi CompareTo: Phương thức thành viên lớp, giúp so sánh 2 chuỗi và trả về 1 giá trị kiểu int. Cách sử dụng: int gt = .CompareTo( ); . Nếu gt = 0: hai chuỗi bằng nhau . Nếu gt = 1: chuỗi 1 lớn hơn chuỗi 2 . Nếu gt = -1: chuỗi 1 nhỏ hơn chuỗi 2 - Phương thức so sánh chuỗi Equal: Phương thức này dùng để so sánh các chuỗi ký tự có giống nhau hay không. Nếu 2 chuỗi hoặc ký tự giống nhau sẽ trả về giá trị true , ngược lại trả về giá trị false. Cách sử dụng: bool gt = String.Equal( , , [StringComparisonType]); Lưu ý: N ếu sử dựng phương thức không chỉ định tham số StringComparisonType thì sẽ so sánh từng ký tự một giữa hai chuỗi và phân biện hoa thường. Nếu muốn không phân biệt chữ hoa thường thì thêm tham số StringComparison.OrdinalIgnoreCase 20
  27. Ví dụ 1.25: public static void Main(string []args) { string str1 = "ITlab"; string str2 = "itlac"; if (String.Equals(str1, str2, StringComparison.OrdinalIgnoreCase)) MessageBox.Show("Chuoi giong nhau "); else MessageBox.Show("Chuoi khong giong nhau "); }  Nhóm phƣơng thức nối chuỗi và chèn chuỗi: Concat, Join, Inser - Phương thức Concat: Phương thức tĩnh Concat dùng để nối hai hay nhiều chuỗi lại với nhau và trả về 1 chuỗi mới Cách sử dụng: string = String.Concat( , ); Ví dụ 1.26: public static void Main(string []args) { string chuoi1=“abc”; string chuoi2=“aBc”; string kq = String.Concat(chuoi1,chuoi2); //kq = “abcaBc” } - Phương thức Join: dùng để nối 1 mảng chuỗi lại với nhau, giữa các phần tử có thể chèn thêm 1 chuỗi nào đó để phân cách. Cách sử dụng: string = String.Join( , ); Ví dụ 1.27: public static void Main(string []args) { string[] chuoi = { "mot", "hai", "ba" }; string str = String.Join(" ", chuoi); } //str = “mot hai ba - Phương thức Insert: Phương thức thuộc lớp, giúp chèn 1 chuỗi vào 1 vị trí xác định trong chuỗi khác. 21
  28. Cách sử dụng: string = .Join( , ); Ví dụ 1.28: public static void Main(string []args) { string chuoi = “mot hai bon”; string str = chuoi.Insert(3, “ hai”); //str = “mot hai ba bon” }  Nhóm phƣơng thức kiểm tra và định vị: Contain, StartsWith, EndsWith, IndexOf, IndexOfAny, LastIndexOf, LastIndexOfAny - Phương thức Contain: Phương thức thuộc lớp, giúp các tìm một từ hoặc một chuỗi bất kỳ trong một chuỗi khác. Nếu tìm thấy trả về true, không tìm thấy trả về false Cách sử dụng: bool gt= .Contain( ) Chuoi2: có thể là một ký tự hoặc 1chuỗi. Phương thức Contain sẽ kiểm tra chuoi2 có trong chuoi1 không, việc tìm kiếm này có sự phân biệt giữa ký tự hoa và ký tự thường. Ví dụ 1.29: public static void Main(string []args) { string str = null; str = "Diễn đàn công nghệ và giải pháp"; if (str.Contains("công nghệ") == true) MessageBox.Show("Chuỗi trên có chứa từ 'công nghệ' "); else MessageBox.Show("Chuỗi trên không chứa từ 'công nghệ'"); }//Hiển thị Messagebox: Chuỗi trên có chứa từ „công nghệ‟ - Phương thức StartsWith: Phương thức thuộc lớp, kiểm tra xem chuỗi có bắt đầu bởi 1 số ký tự nào đó không. Phương thức này có kiểu trả về là Boolean: true/false. bool gt= .StartsWith( ) Chuoi2: Là chuỗi cần kiểm tra xem có là chuỗi bắt đầu của chuoi1 không. Vi ệc kiểm tra này có phân biệt ký tự hoa và ký tự thường. 22
  29. Ví dụ 1.30: public static void Main(string []args) { string str = null; str = "Diễn đàn công nghệ và giải pháp"; if (str. StartsWith ("diễn đàn") == true) MessageBox.Show("Chuỗi str bắt đầu với „diễn đàn‟"); else MessageBox.Show("Chuỗi str không bắt đầu với „diễn đàn‟"); }//Hiển thị Messagebox: Chuỗi str không bắt đầu với „diễn đàn‟ Nếu muốn việc tìm kiếm không phân biệt ký tự hoa và ký tự thường cần thêm tham số StringComparisonType trong phương thức: Cách sử dụng: bool gt= .StartsWith( , [StringComparisonType]) Ví dụ 1.31: public static void Main(string []args) { string str = null; str = "Diễn đàn công nghệ và giải pháp"; if (str.StartsWith("diễn đàn",StringComparison.OrdinalIgnoreCase) == true) MessageBox.Show("Chuỗi str bắt đầu với „diễn đàn‟"); else MessageBox.Show("Chuỗi str không bắt đầu với „diễn đàn‟"); }//Hiển thị Messagebox: Chuỗi str bắt đầu với „diễn đàn‟ - Phương thức EndsWith: Phương thức thuộc lớp, kiểm tra xem chuỗi có kết thúc bởi 1 số ký tự nào đó không. Phương thức này có kiểu trả về là Boolean: true/false. bool gt= .EndsWith( ) Chuoi2: Là chuỗi cần kiểm tra xem có là chuỗi kết thúc của chuoi1 không. Việc kiểm tra này có phân biệt ký tự hoa và ký tự thường. 23
  30. Ví dụ 1.32: public static void Main(string []args) { string str = null; str = "Diễn đàn công nghệ và giải pháp"; if (str. EndsWith ("giải pháp") == true) MessageBox.Show("Chuỗi str kết thúc với „giải pháp‟"); else MessageBox.Show("Chuỗi str không kết thúc với „giải pháp‟"); }//Hiển thị Messagebox: Chuỗi str kết thúc vói „giải pháp‟ - Phương thức IndexOf: Phương thức thuộc lớp, trả về chỉ số của ký tự đầu tiên mà chuỗi xuất hiện, nếu không tìm thấy sẽ trả giá trị -1. Cách sử dụng: int vitri= .IndexOf( ) Chuoi2: là chuỗi cần tìm kiếm trong chuoi1. Ví dụ 1.33: public static void Main(string []args) { string str1 = "Chao ngay ngay moi"; string str2 = "ngay"; int vitri = str1.IndexOf(str2)); } //vitri = 5 - Phương thức LastIndexOf: Phương thức thuộc lớp, tìm kiếm bắt đầu từ cuối chuỗi về đầu, trả về chỉ số của ký tự đầu tiên mà chuỗi xuất hiện. Nếu không tìm thấy sẽ trả giá trị -1. Cách sử dụng: int vitri= .LastIndexOf( ) Chuoi2: là chuỗi cần tìm kiếm trong chuoi1. Ví dụ 1.34: public static void Main(string []args) { string str1 = "Chao ngay ngay moi"; string str2 = "ngay"; int vitri = str1.LastIndexOf(str2)); } //vitri = 10 24
  31. - Phương thức IndexOfAny: Phương thức thuộc lớp, tìm kiếm chỉ số xuất hiện của từng ký tự trong chuỗi so với mảng ký tự đầu vào, nếu không tìm thấy sẽ trả giá trị -1. Cách sử dụng: int vitri= .LastIndexOf( ) T ừng ký tự trong chuoi1, bắt đầu từ ký tự đầu tiên của chuoi1 sẽ lần lượt đươc so sánh với các ký tự trong mảng ký tự đầu vào, nếu tìm thấy một ký tự nào đó trong chuoi1 xuất hiện trong mảng ký tự sẽ trả về vị trí của ký tự đó trong chuoi1. Ví dụ 1.35: public static void Main(string []args) { string str1 = "Chao ngay ngay ngay moi"; char[] mangkytu = {'n','g','a','y'}; int vitri = str1.IndexOfAny(mangkytu); //vitri = 2 } - Phương thức LastIndexOfAny: Phương thức thuộc lớp, tìm kiếm chỉ số xuất hiện của từng ký tự trong chuỗi so với mảng ký tự đầu vào, nếu không tìm thấy sẽ trả giá trị -1. Cách sử dụng: int vitri= .LastIndexOf( ) Từ ng ký tự trong chuoi1, bắt đầu từ ký tự cuối chuoi1 sẽ lần lượt đươc so sánh với các ký tự trong mảng ký tự đầu vào, nếu tìm thấy một ký tự nào đó trong chuoi1 xuất hiện trong mảng ký tự sẽ trả về vị trí của ký tự đó trong chuoi1. Ví dụ 1.36: public static void Main(string []args) { string str1 = "Chao ngay ngay ngay moi"; char[] mangkytu = {'n','g','a','y'}; int vitri = str1.LastIndexOfAny(mangkytu); //vitri = 18 }  Nhóm phƣơng thức trích chọn xâu con từ chuỗi: Substring, Split. - Phương thức Substring: Trích một chuỗi con từ một chuỗi có sẵn, trả về một chuỗi mới. Cách sử dụng: string kq = .Substring(start, len); 25
  32. start: Vị trí ký tự bắt đầu trích trong chuoi1 len: Số ký tự sẽ trích ra trong chuoi1 Ví dụ 1.37: public static void Main(string []args) { string str1 = "Chao ngay moi"; string str=str1.Substring(5, 4); //str = “ngay” } Ngoài ra có thể trích chọn chuỗi con từ vị trí chỉ định đến cuối chuỗi bằng cách bỏ đi tham số len trong phương thức Substring. Cách sử dụng: string kq = .Substring(start); start: Vị trí ký tự bắt đầu trích trong chuoi1 Ví dụ 1.38: public static void Main(string []args) { string str1 = "Chao ngay moi"; string str=str1.Substring(5); //str = “ngay moi” } - Phương thức Split: Phương thức thành viên của lớp. Sử dụng tách chuỗi lớn thành các chuỗi con. Cách sử dụng: string []kq = .Substring( ); : Là một ký tự hoặc một mảng các ký tự sử dụng để làm tiêu chí tách chuoi1 thành các chuỗi con. Ví dụ 1.39: public static void Main(string []args) { string str1 = "Son,Tung,Tuan"; string[] ten = str1.Split(','); } //Kết quả được mảng tên gồm các phần tử: {“Son”, “Tung”, “Tuan”} - Phương thức Remove: Phương thức thuộc lớp, sử dụng để xóa chuỗi Cách sử dụng: string kq = .Remove( , [ ]); 26
  33. : Là vị trí của ký tự trong chuoi1 bắt đầu xóa. : Là số lượng ký tự sẽ xóa trong chuoi1 Ví dụ 1.40: public static void Main(string []args) { string str = “mothaibabonnam"; string str1 = str.Remove(3,8); } //str1 = “motnam” Ngoài ra, Remove còn có thể sử dụng để xóa từ một vị trí chỉ đính đến cuối chuỗi. Cách sử dụng: string kq = .Remove( ); : Vị trí ký tự bắt đầu xóa trong chuoi1. Ví dụ 1.41: public static void Main(string []args) { string str = “mothaibabonnam"; string str1 = str.Remove(8); } //str1 = “motnamba”  Nhóm phƣơng thức sao chép chuỗi: Copy, ToCharArray, CopyTo - Phương thức Copy: Phương thức tĩnh giúp trả về 1 chuỗi nằm trên 1 vùng nhớ khác nhưng cùng nội dung với chuỗi ban đầu. Cách sử dụng: string kq = String.Copy( ); Ví dụ 1.42: public static void Main(string []args) { string str1 = "Chao ngay moi"; string str = String.Copy( str1); } //Tạo ra vùng nhớ mới của str1 đồng thời sao chép nội dung chuỗi str //vào str1. Kết quả str = “Chao ngay moi” 27
  34. - Phương thức ToCharArray: Phương thức thuộc lớp, chuyển 1 chuỗi về 1 mảng ký tự và trả giá trị về là mảng ký tự đó. Cách sử dụng: char[] = .ToCharArray(); : Là chuỗi ký tự cần chuyển đổi về mảng các ký tự. : chứa các ký tự chuyển từ Ví dụ 1.43: public static void Main(string []args) { string str1 = "Chao"; char []chars =str1.ToCharArray(); } //mảng ký tự chars = {„C‟, „h‟, „a‟, „o‟} - Phương thức CopyTo: Phương thức thuộc lớp, giúp sao chép các ký tự trong một chuỗi vào một mảng ký tự, có thể quy định được vị trí và số lượng ký tự trong chuỗi sẽ copy vào mảng ký tự, đồng thời chỉ định copy vào vị trí thứ mấy trong mảng ký tự. Cách sử dụng: void CopyTo(int sourceIndex, char[] destination, int destinationindex, int count) Ví dụ 1.44: public static void Main(string []args) { string str= “chao mung mot ngay moi”; char []chars = new char[10]; str.CopyTo( 5, chars, 0, 8); } //mảng ký tự chars = {„m‟, „u‟, „n‟, „g‟, „ ‟, „m‟, „o‟, „t‟}  Nhóm các phƣơng thức định dạng chuỗi: Padleft, PadRight, ToLower, ToUpper, Trim, TrimStart, TrimEnd. - Phương thức PadLeft: Phương thức thuộc lớp, canh lề phải đồng thời thêm vào bên trái chuỗi một số ký tự đặc biệt. Cách sử dụng: string = . PadLeft(len, [ký tự]) [ký tự]: Ký tự sẽ thêm, nếu trong hàm PadLeft không có tham số [ký tự] thì mặc định sẽ thêm khoảng trắng vào. 28
  35. Ví dụ 1.45: public static void Main(string []args) { string str1 = "Chao"; str1= str1.PadLeft(7); //str1 = “ Chao” string str2=“hello”; str2=str2.PadLeft(8, „*‟); //str2 = “ hello” } - Phương thức PadRight: Phương thức thuộc lớp, canh lề trái đồng thời thêm vào bên phải chuỗi một số ký tự đặc biệt. Cách sử dụng: string = . PadRight(len, [ký tự]) [ký tự]: Ký tự sẽ thêm, nếu trong hàm PadRight không có tham số [ký tự] thì mặc định sẽ thêm khoảng trắng vào. Ví dụ 1.46: public static void Main(string []args) { string str1 = "Chao"; str1= str1.PadRight(7); //str1 = “Chao ” string str2=“hello”; str2=str2.PadRight(8, „*‟); //str2 = “hello ” } - Phương thức ToUpper: Phương thức thuộc lớp, trả về một chuỗi in hoa Cách sử dụng: string = . ToUpper() Ví dụ 1.47: public static void Main(string []args) { string str1 = "Chao"; string str2= str1.ToUpper(); //str2 = “CHAO” } - Phương thức ToLower: Phương thức thuộc lớp, trả về một chuỗi in thường Cách sử dụng: string = . ToLower() 29
  36. Ví dụ 1.48: public static void Main(string []args) { string str1 = "Chao"; string str2= str1.ToLower(); //str2 = “chao” } - Phương thức Trim: Phương thức thuộc lớp, trả về 1 chuỗi đã bỏ khoảng trắng đầu chuỗi và cuối chuỗi. Cách sử dụng: string = . Trim() Ví dụ 1.49: public static void Main(string []args) { string str1 = " Chao ngay moi "; string str2= str1.Trim(); //str2 = “Chao ngay moi” } - Phương thức TrimStart: Phương thức thuộc lớp, trả về 1 chuỗi đã bỏ khoảng trắng đầu chuỗi. Cách sử dụng: string = . TrimStart() Ví dụ 1.50: public static void Main(string []args) { string str1 = " Chao ngay moi "; string str2= str1.TrimStart(); //str2 = “Chao ngay moi ” } - Phương thức TrimEnd: Phương thức thuộc lớp, trả về 1 chuỗi đã bỏ khoảng trắng cuối chuỗi. Cách sử dụng: string = . TrimEnd() Ví dụ 1.51: public static void Main(string []args) { string str1 = " Chao ngay moi "; string str2= str1.TrimEnd(); //str2 = “ Chao ngay moi” } 30
  37. 1.8. Mảng Mảng là một tập hợp có thứ tự của những đối tượng, các đối tượng này cùng một kiểu. Cú pháp khai báo mảng được kết hợp giữa cú pháp khai báo mảng của C và định nghĩa lớp của C#, do đó các đối tượng của mảng có thể truy cập những phương thức và thuộc tính của lớp System.Array. 1.8.1. Mảng một chiều  Cú pháp: [] = new [ ]; Ví dụ 1.52: Khai báo mảng số nguyên có 100 phần tử int [] mang = new int[100]; Hoặc có thể khai báo mảng đồng thời khởi tạo giá trị cho các phần tử mang:  Cú pháp: [] = { , , , ., }; Lưu ý: khi khởi tạo mảng bẳng toán tử new thì các phần tử của mảng sẽ mang giá trị mặc định như bảng 1.5 sau: Bảng 1.5: Bảng mô tả các giá trị mặc định của kiểu dữ liệu Kiểu dữ liệu Giá trị mặc định int, long, byte, 0 bool false char „\0‟ (null) enum 0 reference null  Truy cập các phần tử của mảng: Để truy cập các thành phần trong mảng phải sử dụng toán tử chỉ mục []. Với phần tử đầu tiên trong mảng mang chỉ số số 0. Ngoai ra C# hỗ trợ thuộc tính Length để xác định chiều dài của mang. Ví dụ 1.53: Tính tổng các phần tử của mảng A = {1, 2, 3, 4, 5} public static void Main(string []args) { int[] mang={1,2,3,4,5,6}; int tong = 0; for(int i=0; i<mang.Length; i++) { tong = tong + mang[i]; } } 31
  38. 1.8.2. Mảng hai chiều Trong C#, ngoài việc khai báo mảng một chiều như mục 1.8.1 thì lập trình viên có thể khai mảng hai chiều hoặc nhiều chiều tùy thuộc vào mục đích sử dụng. Và mỗi mảng khi khai báo lại có thể khai báo theo hai dạng khác nhau là mảng đa chiều cùng kích thước hoặc mảng đa chiều không cùng kích thước.  Mảng hai chiều cùng kích thước: Là mảng được tổ chức thành các dòng và các cột, trong đó dòng được tính theo hàng ngang và cột được tính theo hàng dọc của mảng. Trong mảng hai chiều cùng kích thước thì số lượng phần tử trên mỗi dòng là bằng nhau. - Cú pháp: [,] = new [ , ]; Ví d ụ 1.54: Khai báo mảng hai chiều cùng kích thước kiểu số nguyên có 3 dòng 4 cột. int [,] M = new int[3,4]; 4 cột M[0,0] M[0,1] M[0,2] M[0,3] 3 dòng M[1,0] M[1,1] M[1,2] M[1,3] M[2,0] M[2,1] M[2,2] M[2,3] Ví dụ 1.55: Khai báo mảng M có kích thước 2 dòng, 3 cột với các phần tử tương ứng như sau: 1 2 3 4 5 6 Tính tổng các phần tử trong m ảng M public static void Main(string []args) { int[,] M = new int[2,3]; int tong = 0, i, j, k=1; for(i=0; i<2; i++) for(j=0; j<3; j++) { M[i, j] = k; k = k+1; } for(i=0; i<2; i++) for(j=0; j<3; j++) tong = tong + M[i, j]; } 32
  39.  Mảng hai chiều không cùng kích thước: Là mảng được tổ chức thành các dòng và các cột, trong đó dòng được tính theo hàng ngang và cột được tính theo hàng dọc của mảng. Trong mảng hai chiều không cùng kích thước thì số lượng phần tử trên mỗi dòng có thể khác nhau. - Cú pháp: Khi khai báo mảng hai không chiều cùng kích thước phải khai báo số dòng của mảng trước [][] = new [ ][]; Sau khi đã khởi tạo số dòng của mảng, cần khai báo số cột trên từng dòng c ủa mảng: [0] = new [ ]; [1] = new [ ]; [dòng] = new [ ]; Ví dụ 1.56: Khai báo mảng hai chiều có 3 dòng, dòng 1 có 3 cột, dòng hai có 4 cột, dòng 3 có 5 cột. Gán phần tử vị trí dòng 0 và cột 1 giá trị 10 Gán phần tử vị trí dòng 1 và cột 0 giá trị 5 Gán phần tử vị trí dòng 2 và cột 4 giá trị 15 public static void Main(string []args) { int[][] M = new int[3][]; M[0] = new int[3]; M[1] = new int[4]; M[2] = new int[5]; 0 10 0 M[0][1] = 10; M[1][0] = 5; 5 0 0 0 M[2][4] = 15; } 0 0 0 0 15 1.9. Tạo và sử dụng DLL trong C# DLL là từ viết tắt của Dynamic linking library, gọi là thư viện liên kết động, là các module chứa các phương thức và dữ liệu.các phương thức và dữ liệu trong Module này sẽ được đóng gói vào 1 tập tin có đuôi .DLL. 1.9.1. Ƣu điểm và nhƣợc điểm khi sử dụng DLL Một số ưu điểm khi sử dụng DLL: 33
  40.  Giảm không gian sử dụng bộ nhớ: Điều này có nghĩa là sử dụng DLL sẽ làm giảm kích thước của ứng dụng: Do mã lệnh của các hàm trong DLL sẽ không được nhúng vào trong file chương trình của ứng dụng. Khi đó ứng dụng chỉ cần lưu thông tin của hàm trong DLL, và khi cần hệ điều hành sẽ tải các hàm này vào bộ nhớ để ứng dụng sử dụng. Khi không còn sử dụng, có thể giải phóng DLL khỏi bộ nhớ, khi cần nâng cấp, chỉ cần thay thế file DLL, các file chương trình khác không bị ảnh hưởng  Tạo ra khả năng tương tác giữa các ngôn ngữ lập trình: Một ứng dụng có thể sử dụng các DLL viết bằng bất cứ ngôn ngữ lập trình nào. Các nhà phát triển phần mềm chỉ việc đóng gói các module của mình vào trong một DLL với ngôn ngữ ưa thích, sau đó module này có thể được sử dụng trong các ứng dụng viết bằng C++ hay Visual Basic Một số nhược điểm khi sử dụng DLL: Tuy nhiên khi sử dụng DLL thỉnh thoảng sẽ gặp một lỗi sau: The ordinal abc could not be located in the dynamic-link library xyz.dll Lỗi này phát sinh do chương trình cài đặt không kiểm tra phiên bản của các DLL trước khi sao lưu nó vào trong thư mục hệ thống. Khi một DLL mới thay thế một DLL cũ có sẵn, và nếu DLL mới này có một số thay đổi lớn làm cho nó không thể tương thích ngược lại với các chương trình sử dụng phiên bản cũ, nó sẽ làm rối loạn chương trình đó 1.9.2. Các bƣớc để tạo tập tin DLL Bước 1: Tạo mới dự án: Chọn thực đơn File > new > Project như hình 1.8. Hình 1.8: Tạo mới dự án 34
  41. Bước 2: Chọn loại dự án là Class Library và đặt tên “LoiChao” cho tập tin DLL. Bước 1: Chọn loại dự án Bước 2: Đặt tên dự án Hình 1.9: Chọn loại dự án và đặt tên dự án Bước 3: Giao diện soạn thảo mã lệnh được hiển thị, tiến hành viết mã lệnh như hình 1.10. Hình 1.10: Giao diện soạn thảo mã lệnh Bước 4: Nhấn F5 biên dịch để dự án tạo tập tin DLL. Thông thường tập tin DLL được tạo sẽ nằm trong thư mục Bin của dự án hoàn thành công việc tạo tập tin DLL 35
  42. 1.9.3. Các bƣớc để sử dụng tập tin DLL Bước 1: Tạo dự án mới như hình 1.11. Bước 1:Chọn loại dự án Windows Forms Application Bước 2: Đặt tên dự án và chọn đường dẫn lưu trữ Hình 1.11: Tạo dự án mới Bước 2: Bên cửa sổ Solution Explorer, nhấp phải chuột vào References và chọn Add References để thêm *.DLL vào dự án này như hình 1.12. Bước 2: Trên cửa sổ Add Reference chọn tab Browse Bước 3: Tìm đến Bước 4: đường dẫn chứa chọn tập tập tin DLL Bước 1: Nhấp phải chuột tin DLL vào References và chọn Add References Bước 5: Chọn OK Hình 1.12: Thêm tập tin DLL vào dự án Bước 3: Sử dụng tập tin DLL. 36
  43. Khai báo không gian tên của DLL Khai báo đối đượng và sử dụng phương thức trong DLL Hình 1.13: Sử dụng DLL Ví dụ: Xây dựng tập tin DLL hỗ trợ giải phương trình bậc hai. Bước 1: Tao dự án loại Class Library và đặt tên là Giai_phuong_trinh_bac_hai như hình 1.14. Hình 1.14: Tạo dự án Class Library 37
  44. Bước 2: Viết mã lệnh cho điều khiển using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Giai_phuong_trinh_bac_hai { public class PhuongTrinhBacHai { int a, b, c; public int C { get { return c; } set { c = value; } } public int B { get { return b; } set { b = value; } } public int A { get { return a; } set { a = value; } } public string TimNghiem() { string ketqua = ""; double x1=0, x2=0; double delta = b * b - 4 * a * c; if (a != 0) { if (delta < 0) ketqua = "Phương trình vô nghiệm"; else if (delta == 0) { x1 = -b / (2.0 * a); ketqua = "Phương trình có nghiệm kép: " + x1; } else { x1 = (-b - Math.Sqrt(delta)) / (2.0 * a); x1 = (-b + Math.Sqrt(delta)) / (2.0 * a); ketqua = "x1 = " + x1 + " và x2 = " + x2; } } else ketqua = "Đây không phải là phương trình bậc hai"; return ketqua; } } } 38
  45. 1.10. Bài tập cuối chƣơng Bài 1: Tạo tập tin thư viện tên ToaDo.DLL, hỗ trợ cộng và trừ hai tọa độ Bài 2: Tạo tập tin thư viện tên PhanSo.DLL, hỗ trợ cộng, trừ, nhân, chia hai phân số Bài 3: Tạo tập tin thư viện tên PTB1.DLL, hỗ trợ người sử dụng giải phương trình bậc nhất: ax + b = 0 Bài 4: Tạo tập tin thư viện tênPTB4.DLL, hỗ trợ người sử dụng giải phương trình trùng phương: ax4 + bx2 + c = 0 Bài 5: Tạo tập tin thư viện tên HePTB1.DLL, hỗ trợ người sử dụng giải hệ phương trình bậc nhất hai ẩn số: { 39
  46. CHƢƠNG 2: GIỚI THIỆU VỀ WINDOWS FORMS 2.1. Giới thiệu 2.1.1. Ứng dụng Windows Forms Windows Forms là ứng dụng cơ bản của Microsoft; Windows Forms cho phép lập trình viên tạo các form một cách dễ dàng, đồng thời hỗ trợ nhiều điều khiển (Controls) hoặc thành phần (Components) giúp lập trình viên có thể xây dựng, tùy chỉnh các giao diện form một cách nhanh chóng: Tạo ra các form có kích thước và hình dạng khác nhau, bố trí các điều khiển và thành phần trên form phù hợp với nhu cầu, mục đích của người sử dụng. Ngoài ra, trên mỗi điều khiển thì Windows Forms cung cấp nhiều sự kiện giúp tương tác với thiết bị. Lập trình viên có thể sử dụng một cách đa dạng các sự kiện này trên các thiết bị như: sự kiện ấn nút bàn phím, sự kiện nhấp chuột, hoặc sự kiện ấn tổ hợp phím.  Tạo một dự án Windows Forms: Để tạo một dự án Windows Forms với C#, cần thực hiện một số bước sau : Bước 1: Sau khi cài xong Micorsoft Visual Studio 2010, tiến hành bật ứng dụng Visual Studio 2010 lên bằng cách nhấp vào biểu tượng như hình 2.1: Hình 2.1: Mở ứng dụng Visual Studio 2010 40
  47. Bước 2: Sau khi đã chọn biểu tượng Visual Studio 2010 giao diện như hình 2.2 sẽ được hiển thị: Hình 2.2: Giao diện ứng dụng Visual Studio 2010 Bước 3: Chọn Menu File > New > Project Hình 2.3: Giao diện tạo dự án mới Bước 4: Sau khi thực hiện xong bước 3, cửa số New Project sẽ xuất hiện, tại cửa số này lập trình viên có thể chọn ngôn ngữ lập trình sử dụng và chọn loại ứng dụng muốn viết. Cụ thể ở đây chọn ngôn ngữ Visual C#, và loại ứng dụng là Windows Forms. Sau khi đã chọn xong loại ứng dụng đã viết, lập trình viên cần đặt tên cho dự án (nếu không muốn sử dụng tên mặc định của Visual Studio) và đường dẫn sẽ lưu dự án như hình 2.4: 41
  48. Chọn ngôn ngữ lập trình Chọn loại ứng dụng Đặt tên cho dự án Chọn đường dẫn lưu dự án Hình 2.4: Cửa sổ New Project Sau khi đã tạo xong dự án, một form mới có tên Form1 mặc định sẽ được thêm vào dự án vừa tạo như hình 2.5. Lúc này lập trình viên có thể thiết kế giao diện của Form1 bằng cách thêm các thành phần cần thiết phù hợp với nhu cầu của phần mềm. Thanh menu Thanh titlebar Giao diện ban đầu của form Hình 2.5: Giao diện chính của dự án Windows Forms 42
  49.  Thêm form mới vào dự án: Phần lớn các dự án phần mềm đều chứa rất nhiều form . Do đó lập trình viên có thể thêm một form mới vào dự án và thiết kế form đó tại thời điểm thiết kế hoặc lập trình viên có thể thêm form mới bằng cách viết các đoạn mã tạo form và form mới sẽ được tạo ra tại thời điểm thực thi của chương trình. Để thêm một form mới vào dự án tại thời điểm thiết kế, trên menu Project, chọn Add Windows Form. Một hộp thoại Add New Item được mở ra. Sau đó chọn mục Windows Form và đặt tên cho form mới như hình 2.6. Nhấp Add để hoàn tất việc thêm form mới vào dự án phần mềm. Chọn Windows Form Đặt tên cho form mới Hình 2.6: Cửa sổ Add New Item Để thêm một Form mới sau khi đã hoàn thành việc thiết kế giao diện, lập trình viên sẽ phải viết các đoạn mã chương trình tạo form và sau đó form mới sẽ được tạo và hiển thị trong quá trình chương trình được thực thi. Khái báo đối tượng thuộc lớp Form như sau: Form form1; form1 = new Form(); Hiển thị Form khi tại thời điểm chương trình thực thi cần sử dụng đến phương thức Show() hoặc ShowDialog(): form1.Show(); 43
  50. 2.1.2. Không gian tên (namespace) Namespace được gọi là không gian tên. Ý nghĩa lớn của việc sử dụng không gian tên là tránh sự xung đột tên lớp (class) trong một dự án (project). Ngoài ra, không gian tên còn giúp phân nhóm những lớp có cùng chức năng nhằm giúp dễ dàng quản lý mã nguồn. Cụ thể, để làm việc với màn hình Console, C# đã tạo ra một lớp Console, lớp này chứa những thuộc tính và phương thức chỉ dành riêng làm việc với môi trường Console, lớp Console này đặt trong không gian tên System; Không gian tên tổ chức dạng phân cấp, y như việc phân cấp của cây thư mục. Trong một không gian tên có thể chứa nhiều lớp, các lớp trong cùng một không gian tên không được trùng tên. Hình 2.7 cho thấy sự phân cấp của không gian tên: Không gian tên System chứa không gian tên Data; Không gian tên Data chứa không gian tên Oracle và SqlClient; Trong không gian tên SqlClient chứa nhiều lớp khác tên nhau như: lớp SqlCommand, lớp SqlConnection, System Console Data Oracle SqlCommand SqlClient SqlConnection Hình 2.7: Tổ chức phân cấp của không gian tên trong C#  Sử dụng không gian tên: C# xây dựng sẵn nhiều lớp đối tượng đặt trong các không gian tên khác nhau phục vụ cho việc lập trình. Để sử dụng không gian tên trong C#, cần sử dụng từ khóa using. Ví dụ 2.1: using System; using System.Windows.Forms; Khi tạo một dự án kiểu Windows Application, mặc định dự án sẽ sử dụng 8 không gian tên sau: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; 44
  51. using System.Linq; using System.Text; using System.Windows.Forms; Ý nghĩa của các không gian tên như sau: - Không gian tên System: Chứa các lớp và các kiểu dữ liệu cơ sở (int, double, byte, short, ). - Không giam tên System.Data: Chứa các lớp của ADO.NET, các lớp giúp kết nối hoặc thao tác với cơ sở dữ liệu (SQL Server, Oracle, Microsoft Access). - Không gian tên System.Drawing: Chứa các lớp làm việc với đồ họa. - Không giam tên System.ComponentModel: Chứa các lớp cơ sở và giao diện giúp thực thi chuyển đổi kiểu, thuộc tính, liên kết với các dữ liệu nguồn và các thành phần cấp phép - Không gian tên System.Collections.Generic: Chứa các lớp hỗ trợ cho việc thiết lập các tập hợp dạng chung mẫu (template) như: . ArrayList List : Tập hợp chung mẫu có thể thay đổi kích thước khi vận hành. . Queue Queue : Tập hợp chung mẫu theo mô hình vào trước ra trước(FIFO). . Stack Stack : Tập hợp chung mẫu theo mô hình vào sau ra trước (LIFO) . - Không gian tên System.Text: Cung cấp các lớp giúp mã hóa các ký tự Ascii hoặc Unicode. - Không gian tên System.Linq: Cung cấp các lớp hỗ trợ cho việc sử dụng ngôn ngữ truy vấn tích hợp (Language-Integrated Query – LinQ). - Không gian tên System.Windows.Forms: Là không gian tên chính cung cấp các lớp để xây dựng ứng dụng kiểu Windows Application. Không gian tên System.Windows.Forms chia thành các nhóm sau: . Control, UserControl, Form . Menu, toolbar: ToolStrip, MenuStrip, ContextMenuStrip, StatusStrip . Controls: TextBox, ComboBox, ListBox, ListView, WebBrowser, Label, . Layout: FlowLayoutPanel, TableLayoutPanel, Giúp trình bày các điều khiển trên form. 45
  52. . Data và DataBinding: Gồm các công cụ BindingNavigator, BindingSource, giúp liên kết dữ liệu từ cơ sở dữ liệu đến các điều khiển Dataset hoặc DataGridView. . Command Dialog Boxes: Gồm các điều khiển OpenFileDialog, SaveFielDialog, ColorDialog, FontDialog, PrintDialog làm việc với tập tin, màu sắc, phông chữ, in ấn. 2.1.3. Thanh công cụ (Toolbox) Cung cấp danh sách các Component/ Control được liệt kê theo nhóm, cho phép lập trình viên sử dụng thao tác kéo thả vào form để thiết kế giao diện chương trình. Khi tạo xong dự án, thì giao diện chính của dự án được hiển thị như hình 2.8. Phía bên tay trái hình 2.8 là thanh công cụ. Ngoài những điều khiển hiển thị mặc định trong thanh công cụ, lập trình viên cũng có thể thêm các thành phần mới vào bằng các chọn Project/AddReference. Hộp công cụ Hình 2.8: Giao diện chính với thanh công cụ bên trái Nếu giao diện chính không hiển thị thanh công cụ, lập trình viên có thể hiển thị bằng cách chọn View/ Toolbox như hình 2.9. 46
  53. Hình 2.9: Hiển thị thanh công cụ Thanh công cụ bố trí các điều khiển thành những nhóm riêng biệt như hình 2.10: Chứa các điều khiển thông Ch ứa các điều khiển giúp trình bày dụng như: TextBox, Label, các điểu khiển khác trên form Chứa các điều khiển giúp tạo thanh thực đơn và thanh Chứa các điều khiển trạng thái: MenuStrip, giúp làm việc với cơ StatusStrip sở dữ liệu Chứa các điều khiển giúp Chứa các điều khiển kiểm tra dữ liệu nhập như: giúp làm việc với việc ErrorProvider, HelpProvider in ấn: PrintDialog, PrintReviewDialog Chứa các điều khiển làm việc với tập tin Chứa điều khiển cho Chứa các điều khiển làm phép đặt điều khiển việc với báo cáo của WPF trong cửa sổ Windows Form: Chứa điều khiển cho phép vẽ các hình ô ElemenHost vuông, hình tròn, trên form, hoặc in form. Hình 2.10: Thanh công cụ Với việc phân loại các điều khiển theo nhóm giúp cho lập trình viên dễ dàng tìm kiếm điều khiển cần sử dụng hơn. 47
  54. 2.1.4. Định dạng mã C# Để định dạng mã lệnh khi lập trình. Lập trình viên của thể tùy chỉnh lại định dạng mã trong cửa sổ Option. Đầu tiên bật cửa sổ Option bằng cách chọn Tools/ Options như hình 2.11: Hình 2.11: Giao diện cửa sổ Option Sau khi đã mở cửa sổ Option, chọn mục Evironment/ Fonts and Colors như hình 2.12 để định dạng lại mã lệnh: Kích thước hiển thị Font chữ hiển thị Mục muốn định dạng Màu nền mã lệnh như: chú thích, chuỗi văn bản, từ khóa, Màu của mã lệnh Hình 2.12: Giao diện định dạng mã lệnh 2.2. Các loại Form 2.2.1. Thuộc tính Form  Thiết lập giá trị thuộc tính form trong cửa sổ Properties: 48
  55. Windows Forms hỗ trợ nhiều thuộc tính cho việc tùy chỉnh form. Lập trình viên có thể thay đổi giá trị các thuộc tính này trong cửa sổ Properties như hình 2.13 để điều chỉnh kích thước, màu sắc, font chữ, của form cho phù hợp. Hình 2.13: Giao diện cửa sổ Properties Bảng 2.1 mô tả một số thuộc tính thường sử dụng trong việc thiết kế form Bảng 2.1: Bảng mô tả thuộc tính Form Thuộc tính Mô tả Name Đặt tên form AcceptButton Giá trị thuộc tính này nhận là tên của một button trên form. Khi đó thay vì nhấp chuột vào button để thực thi thì người dùng có thể ấn phím Enter trên bàn phím Backcolor Thiết lập màu nền của form BackgroundImage Thiết lập hình nền cho form BackgroundImageLayout Thiết lập việc hiển thị hình vừa thêm trong thuộc tính BackgroundImage sẽ hiển thị trên form ở dạng: bình thường (None), giữa (Center), CancelButton Giá trị thuộc tính này nhận là tên của một button trên form. Khi đó thay vì nhấp chuột vào button để thực thi thì người dùng có thể ấn phím Escape trên bàn phím ControlBox Mang giá trị true hoặc false. Nếu thiết lập 49
  56. thuộc tính là false thì sẽ loại bỏ các nút minimize và nút maximize trên form Cusor Thiết lập hình dạng con trỏ khi di chuyển con trỏ vào form Enable Mang giá trị true hoặc false; Nếu thiết lập thuộc tính là false thì điều khiển trong form sẽ không cho phép người dùng thao tác. Font Thiết lập văn bản hiển thị trên điều khiển ForeColor Thiết lập màu mặc định cho chuỗi của các điều khiển trên form FormBorderStyle Thiết lập đường viền của form và hành vi của form khi chạy chương trình HelpButton Mang giá trị true hoặc false; Nếu thiết lập thuộc tính là true thì trên thanh titlebar sẽ hiện 1 nút có dấu ? (nút này chỉ hiện khi hai thuộc tính MinimizeBox và MaximizeBox được thiết lập là false) Icon Biểu tượng hiển thị bên trái trên thanh titlebar của form KeyReview Mang giá trị true hoặc false: nếu thiết lập thuộc tính là true cho phép các sự kiện bàn phím của form có hiệu lực Location Khi thuộc tính StartPosition được thiết lập là Manual, thì thuộc tính Location có tác dụng thiết lập vị trí hiển thị của form trên màn hình MaximizeBox Mang giá trị true hoặc false: nếu thiết lập thuộc tính là false thì nút maximize form trên thanh titlebar sẽ mất đi MaximumSize Thiết lập kích thước lớn nhất của form (chiều rộng x chiều cao) MinimizeBox Mang giá trị true hoặc false: nếu thiết lập thuộc tính là false thì nút minimize form trên thanh titlebar sẽ mất đi MinimumSize Thiết lập kích thước nhỏ nhất của form (chiều rộng x chiều cao) 50
  57. Opacity Thiết lập độ trong suốt cho form Size Kích thước form StartPosition Vị trí hiển thị của form trên màn hình Text Chuỗi văn bản hiển thị trên titlebar của form TopMost Mang giá trị true hoặc false: nếu thiết lập thuộc tính là true thì form sẽ luôn hiển thị trên các cửa sổ khác Visible Mang giá trị true hoặc false: nếu thiết lập thuộc tính là true thì form sẽ được hiển thị trên màn hình, nếu là false sẽ không hiển thị trên màn hình WindowState Có 3 giá trị: Normal: hiển thị form bình thường; Minimized: khi chạy chương trình form sẽ bị thu nhỏ dưới thanh taskbar; Maximized: form hiển thị có kích thước đầy màn hình IsMDIContainer Mang giá trị True hoặc False. - Nếu là True: Form ở dạng MDI Form - Nếu là False: Form ở dạng bình thường MdiParent mang giá trị là đối tượng MDI Form. Khi thiết lập giá trị cho thuộc tính MdiParent thì form sẽ trở thành Child Form  Thiết lập giá trị thuộc tính form bằng mã lệnh: Ngoài việc thiết kế form bằng việt thiết lập các giá trị trong cửa sổ properties. Lập trình viên cũng có thể thiết lập giá trị thuộc tính của form bằng mã lệnh như sau: - Thay đổi chuỗi văn bản hiển thị trên titlebar bằng cách thiết lập giá trị cho thuộc tính Text: Form1.Text = “Đây là Form1”; - Thiết lập kích thước form: Có thể thiết lập giá trị cho thuộc tính Width và thuộc tính Height để quy định chiều rộng và chiều cao cho form. Form1.Width = 300; Form1.Height = 400; 51
  58. hoặc: Form1.Size = new Size(300, 400); Lưu ý: Nếu thuộc tính StartPosition được thiết lập là WindowsDefaultBounds, thì form sẽ được thiết lập kích thước mặc định. StartPosition được thiết lập giá trị khác thì kích thước form sẽ được thiết lập như quy định ở thuộc tính Size. - Thiết lập độ trong suốt cho form: Form1.Opacity = 0.5; - Thiết lập vị trí hiển thị của form: Sử dụng thuộc tính StartPosition để thiết lập vị trí hiển thỉ bạn đầu của form trên màn hình. Giá trị thiết lập của thuộc tính StartPosition là một trong các giá trị quy định sẵn trong biến kiểu liệt kê FormStartPosition: Bảng 2.2: Mô tả các giá trị của FormStartPosition Giá trị Mô tả Manual Nếu StartPosition mang giá trị Manual thì vị trí form hiển thị sẽ là vị trí thiết lập tại thuộc tính Size. CenterScreen Form hiển giữa màn hình WindowsDefaultLocatio Form hiển thị tại vị trí mặc định với kích thước n form sẽ là kích thước form được thiết lập tại thuộc tính Size WindowsDefaultBounds Form hiển thị tại vị trí mặc định với kích thước form sẽ là kích thước mặc định CenterParent Form hiển thị ở vị trí giữa form cha Ví dụ 2.2: Hiển thị Form1 ở vị trí giữa màn hình Form1.StartPosition = FormStartPosition.WindowsDefaultLocation;  Thiết lập form hiển thị: Trong C#, lập trình viên có thể thiết lập form hiển thị đầu tiên khi dự án được thực thi bằng cách sửa lại mã lệnh trong hàm main của lớp Program như hình 2.14: 52
  59. Lớp Program mặc định được tao ra trong dự án Các đoạn mã mặc định trong lớp Program Hình 2.14: Lớp Program Lớp Program chứa một hàm bên trong là hàm Main. Khi dự án được thực thi, thì mã lệnh trong hàm Main sẽ thực thi trước. Cụ thể tại dòng: Application.Run(new Form1()); Dòng lệnh trên chỉ ra rằng form đầu tiên sẽ hiển thị là Form1. Do đó, lập trình viên chỉ cần sữa lại mã lệnh chỉ định một form khác muốn hiển thị bằng cách thay tên form đó cho Form1. Ví dụ 2.3: Hiển thị form có tên Form2 trong dự án Application .Run(new Form2()); 2.2.2. Các loại Form Trong ứng dụng Windows Forms, có 3 loại form: form bình thường (Normal Form), form cha (Mdi Form), form con (Child Form).  Mdi Form: Mdi Form là form có thể chứa các Child Form bên trong. Để làm được công việc đó thì form phải được thiết lập thuộc tính: IsMdiContainer = True; Lập trình viên có thể thiết lập thuộc tính IsMdiContainer trong cửa sổ Properties trên màn hình thiết kế form, hoặc bằng mã lệnh. Khi đã thiết lập thuộc tính IsMdiContainer là True thì hình dạng form sẽ thay đổi như hình 2.15. 53
  60. Hình 2.15: Hình dạng form khi chuyển từ Normal Form sang Mdi Form  Child Form: Child Form là dạng form nằm bên trong vùng làm việc của Mdi Form hay nói cách khác là Child Form được chứa bên trong Mdi Form. Một form muốn trở thành Child Form cần phải khai báo thuộc tính MdiParent có giá trị là đối tượng Mdi Form. Thuộc tính MdiParent không được biểu diễn trên cửa sổ Properties, do đó lập trình viên bắt buộc phải thiết lập giá trị MdiParent bằng mã lệnh. Ví dụ 2.4: Viết chương trình biểu diễn Mdi Form và Child Form như hình 2.16. Hình 2.16: Mdi Form và Child Form Hướng dẫn: Bước 1: Tạo một dự án mới bằng C#, loại dự án là Windows Forms Application. Giao diện đầu tiên của chương trình hiển thị Form1 như hình 2.17. 54
  61. Hình 2.17: Giao diện Form1 khi tạo dự án Bước 2: Viết mã lệnh cho chương trình Tại sự kiện Load của Form1 viết các dòng lệnh sau: private void Form1_Load(object sender, EventArgs e) { this.Text = "Mdi Form"; this.IsMdiContainer = true; Form frm = new Form(); frm.Text = "Child Form"; frm.MdiParent = this; frm.Show(); } Bước 3: Nhấn Ctrl + Shift + B để biên dịch mã nguồn và nhấn F5 để thực thi chương trình sẽ được Mdi Form và Child Form như hình 2.16.  Normal Form: Normal Form là form hoạt động độc lập với tất cả các form khác, nghĩa là form sẽ không chứa hoặc được chứa bởi một form nào khác. Thông thường khi tạo mới dự án Windows Forms Application thì form mặc định được tạo và hiển thị đầu tiên là Normal Form. Giao diện của Normal Form như hình 2.17. 2.2.3. Các hình dạng của Form Windows Forms mặc định các form được tạo ra đều ở dạng hình chữ nhật. Nếu lập trình viên muốn tạo form với hình dạng khác như hình tròn hoặc hình đa giác thì cần thiết lập lại thuộc tính Region của form trong sự kiện Form_Load. Tuy nhiên, lập trình viên không thể thấy được hình dạng mới của form trong lúc thiết kế mà chỉ có thể 55
  62. thấy được hình dạng khác của form khi chương trình được thực thi. Do đó sẽ cần phải thực thi chương trình nhiều lần để kích thước form phù hợp với nhu cầu thiết kế. Ví dụ 2.5: Thiết kế form có hình ellipse có chiều rộng là 300 và chiều cao là 200 Bước 1: Tạo sự kiện Form_Load bằng cách nhấp đúp chuột vào màn hình thiết kế form như hình 2.18: Nhấp đúp chuột vào màn hình thiết kế của form Hình 2.18: Màn hình thiết kế form Bước 2: Sau khi tạo ra sự kiện Form_Load, tiến hành viết các dòng lệnh trong sự kiện Form_Load như sau: private void Form1_Load(object sender, EventArgs e) { System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); path.AddEllipse(0, 0, 300, 200); Region myRegion = new Region(myPath); this.Region = myRegion; } Bước 3: Ấn F5 để thực thi chương trình, khi chương trình được thực thi sẽ được form như hình 2.19: 56
  63. Hình 2.19: Form hình Ellipse 2.2.4. Biến cố của Form Biến cố của form hay có thể gọi là các hành động hoặc sự kiện liên quan đến form. Ứng dụng Windowns Forms được hỗ trợ nhiều sự kiện và các đoạn mã tạo ra các sự kiện đều được sinh ra một cách tự động. Để sử dụng các sự kiện của form lập trình viên cần thực hiện các thao tác sau: Bước 1: Nhấp chuột trái vào form Bước 2: Trên cửa sổ Properties tương ứng, nhấp chuột trái vào biểu tượng để mở hộp thoại các sự kiện như hình 2.20. Bước 3: Hộp thoại hình 2.20 chứa nhiều sự kiện liên quan đến form như: đóng form, mở form, di chuyển chuột vào form, Lập trình viên muốn sử dụng sự kiện nào chỉ cần nhấp đôi chuột trái vào sự kiện đó. Danh sách các sự kiện của form Hình 2.20: Danh sách sự kiện form 57
  64. Ví dụ 2.6: Muốn sử dụng sự kiện nhấp chuột của form chỉ cần nhấp đôi chuột vào sự kiện Click thì một phương thức nhấp chuột của form sẽ được tự động phát sinh mã lệnh: private void Form1_Click(object sender, EventArgs e) { //Mã lệnh khi nhấp chuột vào form }  Bảng mô tả các sự kiện thường sử dụng của form: Bảng 2.3: Bảng mô tả các sự kiện của form Sự kiện Mô tả AutoSizeChanged Xảy ra khi thuộc tính Autosize của Form chuyển từ True sang False hay ngược lại là False sang True BackColorChanged Xảy ra khi thuộc tính BackColor của Form thay đổi Click Xảy ra khi người dùng Click chuột vào vùng làm việc thuộc Form ControlAdded Xảy ra khi một điều khiển được Add vào Form ControlRemoved Xảy ra khi một điều khiển bị xóa khỏi Form CursorChanged Xảy ra khi thuộc tính Cursor của Form thay đổi DoubleClick Xảy ra khi người dùng DoubleClick vào vùng làm việc của Form FontChanged Xảy ra khi thuộc tính Font của Form có sự thay đổi ForeColorChanged Xảy ra khi thuộc tính ForeColor của Form có sự thay đổi FormClosed Xảy ra khi Form đã đóng (Nhấn vào nút X màu đỏ trên titlebar) FormClosing Xảy ra khi Form đang đóng (2 sự kiện FormClosed và FormClosing thường dùng trong lập trình CSDL: khi xảy ra sự kiện này thì đóng kết nối CSDL) KeyDown Xảy ra khi người dùng nhấn một phím hay một tố hợp phím KeyPress Xảy ra khi người dùng nhấn một phím KeyUp Xảy ra khi người dùng nhả một phím MouseClick Xảy ra khi người dùng nhấn chuột (một trong 3 lựa chọn: Trái, giữa, phải) MouseDoubleClick Xảy ra khi người dùng nhấp đúp chuột vào một vùng làm việc của Form (một trong 3 lựa chọn: Trái, 58
  65. giữa, phải) MouseDown Xảy ra khi người dùng nhấn chuột MouseHover Xảy ra khi người dùng di chuyển vào các vùng làm việc Form MouseLeave Xảy ra khi di chuyển chuột ra khỏi vùng làm việc của Form MouseMove Xảy ra khi di chuyển chuột trên một vùng làm việc thuộc Form (nếu Form có chứa một điều khiển nào đó, khi di chuyển chuột trên điều khiển này thì không xảy ra sự kiện MouseMove của Form) MouseUp Xảy ra khi người dùng nhả nhấn chuột (có thể là chuột trái, chuột phải, chuột giữa - chuột cuộn) Move Xảy ra khi di chuyển Form (có sự thay đổi vị trí của Form) StyleChanged Xảy ra khi thuộc tính FormBorderStyle của Form thay đổi TextChanged Xảy ra khi thuộc tính Text của Form thay đổi. Sự kiện FormClosed: Sự kiện này được gọi khi Form đã đóng private void frmForm_FormClosed(object sender, FormClosedEventArgs e) { MessageBox.Show(“Sự kiện FormClosed được gọi”); } Sự kiện FormClosing: Xảy ra khi Form đang đóng private void frmForm_FormClosing(object sender, FormClosingEventArgs e) { DialogResult kq = MessageBox.Show("Bạn muốn đóng Form lại không?", "FormClosing", ,MessageBoxButtons.YesNo, MessageBoxIcon.Information); if ( kq == DialogResult.Yes) e.Cancel = false; // Đóng Form lại else e.Cancel = true; //Không đóng Form nữa } 59
  66. Sự kiện KeyPress: Xảy ra khi ấn phím, nếu không chỉ rõ phím nào được nhấn thì khi nhấn bất cứ phím nào của sự kiện KeyPress của form đều xảy ra. private void frmForm_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar = 'a') //nhấn phím a trên bàn phím MessageBox.Show("Sự kiện KeyPress được gọi"); } Sự kiện KeyDown: private void frmForm_KeyDown(object sender, KeyEventArgs e) { // Nhấn Ctrl+F gọi sự kiện KeyDown if (e.KeyCode == Keys.F && e.Modifiers == Keys.Control) MessageBox.Show("Sự kiện KeyDown được gọi"); } Sự kiện MouseClick: Xảy ra khi nhấn một trong 3 nút: chuột trái, giữa hoặc chuột phải. private void frmForm_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) //nhấn chuột trái MessageBox.Show("Sự kiện MouseClick được gọi"); else if (e.Button==MouseButtons.Middle)//nhấn chuột giữa MessageBox.Show("Sự kiện MouseClick được gọi"); else if(e.Button==MouseButtons.Right)//nhấn chuột phải MessageBox.Show("Sự kiện MouseClick được gọi"); } 2.2.5. Phƣơng thức Một số phương thức thường sử dụng của form: Show(), ShowDialog(), Hide(), Close().  Phương thức Show(): Phương thức Show() sử dụng để hiển thị form trên màn hình. 60
  67. Ví dụ 2.7: Thiết kế chương trình như hình 2.21: Giao diện Form1 với: Màu nền form màu xanh, Tiêu đề form là “Giao diện Form 1”, vị trí hiển thị form ở giữa màn hình Hình 2.21: Giao diện Form1 Yêu cầu khi nhấp chuột vào Form1 như hình 2.21 thì sẽ hiển thị Form2 ở giữa màn hình như hình 2.22: Giao diện Form2 với: Màu nền form màu vàng, Tiêu đề form là “Giao diện Form 2”, vị trí hiển thị form ở giữa màn hình Hình 2.22: Giao diện Form2 Hướng dẫn: Bước 1: Tạo Dự án Windows Forms mới với form mặc định ban đầu tên Form1. Bước 2: Thiết lập các thuộc tính cho Form1 như sau: - Thiết lập tiêu đề, màu nền và vị trí hiển thị cho Form1: Trên cửa sổ Properties thiết lập thuộc tính Text, thuộc tính BackColor và thuộc tính StartPosition như hình 2.23: 61
  68. Vị trí hiển thị của Form1 Tiêu đề hiển thị trên titlebar Thiết lập màu nền của Form1 Form1 Hình 2.23: Thiết lập thuộc tính Form1 Sau khi thiết lập xong 3 thuộc tính như hình 2.23 sẽ được Form1 có giao diện như hình 2.21. Bước 3: Tạo sự kiện Click của Form1 và thêm các mã lệnh sau cho sự kiện Click: private void Form1_Click(object sender, EventArgs e) { //Tạo đối tượng lớp Form Form Form2 = new Form(); //Thiết lập tiêu đề trên titlebar của form Form2.Text = "Giao diện Form 2"; //Thiết lập vị trí hiển thị form Form2.StartPosition = FormStartPosition.CenterScreen; //Thiết lập màu nền cho form Form2.BackColor = Color.CadetBlue; //Phương thức Show() giúp hiển thị Form2 Form2.Show(); } Khi bước 3 thực hiện xong và nhấn F5 để thực thi chương trình và Click chuột vào Form1 thì sẽ được Form2 như hình 2.22.  Phương thức ShowDialog(): Phương thức ShowDialog() cũng có tác dụng hiển thị form như phương thức Show(). Nhưng khác biệt cơ bản là phương thức Show() giúp hiển thị form mới lên nhưng người dùng vẫn có thể quay lại thao tác trên các form đang hiển thị trước đó; Còn phương thức ShowDialog() sẽ hiển thị form mới lên và người dùng sẽ chỉ có thể thao tác trên form vừa hiển thị mà không thao tác được trên các form trước đó, do vậy người dùng muốn thao tác lên forn hiển thị trước thì phải đóng form hiện hành bằng phương thức 62
  69. ShowDialog(). Một đặc điểm khác nữa là phương thức ShowDialog() là phương thức trả về hai giá trị là DialogResuilt.OK và DialogResuilt.Cacel. - Phương thức ShowDialog() trả về DialogResuilt.OK khi form đang hiển thị. - Phương thức ShowDialog() trả về DialogResuilt.Cacel khi form đóng. Ví dụ 2.8: Trong sự kiện Click của Form1 như bước 3 trên, tiến hành thay phương thức Show() thành phương thức ShowDialog(). Khi chương trình được thực thi thì người dùng chỉ có thể thao tác với Form2 mà không thể quay trở về Form1 được. private void Form1_Click(object sender, EventArgs e) { //Tạo đối tượng lớp Form Form Form2 = new Form(); //Thiết lập tiêu đề trên titlebar của form Form2.Text = "Giao diện Form 2"; //Thiết lập vị trí hiển thị form Form2.StartPosition = FormStartPosition.CenterScreen; //Thiết lập màu nền cho form Form2.BackColor = Color.CadetBlue; //Phương thức ShowDialog() giúp hiển thị Form2 Form2.ShowDialog(); }  Phương thức Hide(): Phương thức giúp ẩn một form để form đó không hiển thị trên màn hình. Việc ẩn form của phương thức Hide(0 thực chất là thiết lập thuộc tính Visible = false. Ví dụ 2.9: Trong sự kiện Click của Form1 như bước 3, thực hiện yêu cầu là khi nhấp chuột vào Form1 thì Form1 sẽ ẩn đi và Form2 sẽ hiện lên. private void Form1_Click(object sender, EventArgs e) { //this là con trỏ đại diện cho Form hiện hành, Form /hiện hành ở đây là Form1 this.Hide(); Form Form2 = new Form(); Form2.Text = "Giao diện Form 2"; Form2.StartPosition = FormStartPosition.CenterScreen; Form2.BackColor = Color.CadetBlue; Form2.ShowDialog(); } 63
  70.  Phương thức Close(): Sử dụng để đóng form. Ví dụ 2.10: Trong sự kiện Click của Form1 như bước 3, thực hiện yêu cầu là khi đóng Form2 thì Form1 cũng đóng. private void Form1_Click(object sender, EventArgs e) { //Tạo đối tượng lớp Form Form Form2 = new Form(); //Thiết lập tiêu đề trên titlebar của form Form2.Text = "Giao diện Form 2"; //Thiết lập vị trí hiển thị form Form2.StartPosition = FormStartPosition.CenterScreen; //Thiết lập màu nền cho form Form2.BackColor = Color.CadetBlue; //Kiểm tra giá trị trả về của phương thức ShowDialog() //nếu giá trị trả về là DialogResult.Cancel thì Form2 //đã đóng, tiến hành đóng Form1 bằng phương thức //Close() if (Form2.ShowDialog() == DialogResult.Cancel) { this.Close(); } } 2.3. Bài tập cuối chƣơng Câu 1: Trong các dòng mã lệnh sau đây, mã lệnh nào cho phép tạo và hiển thị một đối tượng Windows Form mới có tên là Form1 a) Form1 frm = new Form1; frm.Show(); b) Form Form1 = new Form(); Form1.Show(); c) Form1 frm ; frm.Show(); d) Form frm; frm.Show(); e) Form Form1 = new Form(); Form1.ShowDialog(); Câu 2: Trong các thuộc tính sau, thuộc tính nào dùng để thiết lập nội dung hiển thị trên thanh title bar và thuộc tính nào dùng để thiết lập màu nền của form. a) Thuộc tính Text và ForeColor b) Thuộc tính Display và BackColor c) Thuộc tính Text và BackColor 64
  71. d) Thuộc tính Display và ForeColor Câu 3: Các thuộc tính sau, thuộc tính nào cho phép thiết lập form trở thành Mdi Form a) IsMdiContainer b) MdiParent c) MdiContainer d) ParentForm Câu 4: Các thuộc tính sau, thuộc tính nào cho phép thiết lập form trở thành Child Form a) IsMdiContainer b) MdiParent c) MdiContainer d) ParentForm Câu 5: Trong các sự kiện sau, sự kiện nào sẽ phát sinh khi form đã đóng a) FormClosed b) FormClosing c) ClosedForm d) ClosingForm e) Load f) Click Câu 6: Xây dựng form có dạng hình tam giác như hình 2.21: Hình 2.21: Form hình dạng tam giác 65
  72. CHƢƠNG 3: CÁC ĐIỀU KHIỂN THÔNG THƢỜNG 3.1. Điều khiển Label Label thường dùng hiển thị thông tin chỉ đọc và thường sử dụng kèm với các điều khiển khác để mô tả chức năng. Labelđược đặt trong nhóm Common Controls của cửa số Toolbox như hình 3.1. Điều khiển Label Hình 3.1: Điều khiển Label trong cửa sổ Properties  Một số thuộc tính thường dùng của Label: Bảng 3.1: Bảng mô tả thuộc tính Label Thuộc tính Mô tả BorderStyle Thiết lập đường viền Font Kích thước và kiểu chữ hiển thị trên Label Text Nội dung hiển thị trên Label Backcolor Màu nền của Label Name Tên của Label Locked Khóa không cho di chuyển Enabled Đánh dấu tích là đối tượng sẽ ở trạng thái hoạt động Cursor Đổi hình trỏ chuột khi đưa vào Label ForeColor Thiết lập màu chữ hiển thị trên Label TextAlign Căn lề chữ hiển thị trên Label Visible Ẩn hoặc hiện Label 66
  73. Ví dụ 1: Thiết kế form hiển thị thông tin sinh viên như hình 3.2: Hình 3.2: Giao diện hiển thị thông tin sinh viên Hướng dẫn: Bước 1: Tạo dự án Windows Forms mới, Form1 mặc định tạo sẵn trong dự án đặt tên tiêu đề trên titlebar như sau: “Giao diện Form1” Bước 2: Kéo thả các Label trong cửa sổ Toolbox vào Form1 như hình 3.3 sau: Hình 3.3: Giao diện sau khi kéo Label vào Form1 Bước 3: Thiết lập giá trị thuộc tính cho label1 Nhấp chuột trái vào Form1 và thiết lập thuộc tính Fonttrong cửa sổ Propertiesnhư hình 3.4: Thiết lập kiểu chữ Thiết lập chữ Thiết lập kích in đậm thước chữ 18 Hình 3.4: Cửa sổ thiết lập thuộc tính Font 67
  74. Thiết lập thuộc tính Text cho label1 như hình 3.5: Hình 3.5: Thiết lập thuộc tính Text cho label1 Thiết lập thuộc tính ForeColor như hình 3.6: Hình 3.6: Thiết lập thuộc tính ForeColor Sau khi thiết lập xong thuộc tính Text, giao diện Form1 được như hình 3.7: Hình 3.7: Giao diện Form1 sau khi thiết lập xong thuộc tính cho label1 68
  75. Bước 4: Thiết lập các thuộc tính Font cho label2, label3, label4, label5, label6 như hình 3.8: Hình 3.8: Thiết lập thuộc tính Font cho label2, label3, label4, label5, label6 Thiết lập thuộc tính Text cho label2 như hình 3.9: Hình 3.9: Thiết lập thuộc tính Text cho label2 Thiết lập thuộc tính Text cho label3 như hình 3.10: Hình 3.10: Thiết lập thuộc tính Text cho label3 69
  76. Thiết lập thuộc tính Text cho label4 như hình 3.11: Hình 3.11:Thiết lập thuộc tính Text cho label4 Thiết lập thuộc tính Text cho label5 như hình 3.12: Hình 3.12:Thiết lập thuộc tính Text cho label5 Thiết lập thuộc tính Text cho label6 như hình 3.13: Hình 3.13: Thiết lập thuộc tính Text cho label5 Bước 5: Nhấn F5 thực thi chương trình sẽ được form như hình 3.2. 3.2. Điều khiển Button Button là điều khiển tạo giao diện nút lệnh trên form, khi người dùng nhấn chuột vào nút lệnh thì chương trình sẽ thực hiện một hành động nào đó.Button được đặt trong nhóm Common Controls của cửa số Toolbox như hình 3.14. 70
  77. Điều khiển Button Hình 3.14: Điều khiển Button trong cửa sổ Properties  Một số thuộc tính thường dùng của Button: Bảng 3.2: Bảng mô tả thuộc tính Button Thuộc tính Mô tả Name Đặt tên cho nút lệnh Text Nội dung hiển thị trên nút nhấn Visible Ẩn/ hiện nút nhấn Enable Cho phép/ không cho phép tương tác với nút lệnh Font Chỉ định kiểu chữ, kích cỡ chữ hiển thị ForeColor Màu chữ hiện thị trên nút lệnh Image Hình ảnh hiển thị trên nút lệnh BackColor Màu của nút lệnh TabIndex Chỉ định thứ tự tab của các Button trên form  Một số sự kiện thường dùng của Button: Bảng 3.3: Bảng mô tả sự kiện Button Sự kiện Mô tả Click Sự kiện nhấn chuộtvào Button MouseEnter Chuột nằm trong vùng thấy được của Button MouseHover Rê chuột vào vùng của Button MouseLeave Rê chuột ra khỏi vùng của Button MouseMove Chuột được di chuyển trên Button. Ví dụ 2: Thiết kế form xử lý nút lệnh như hình 3.15. Yêu cầu: Khi nhấp chuột vào nút lệnh “Hiểnthị” thì in sẽ hiển thị chữ “Xin chào” tại vị trí “ nội dung hiển thị ”, khi nhấp chuột vào nút lệnh “Thoát” sẽ đóng chương trình. 71
  78. Hình 3.15: Giao diện form xử lý nút lệnh Hướng dẫn: Bước 1: Kéo các điều khiển từ cửa sổ Toolbox vào form như hình 3.16 Hình 3.16: Giao diện ban đầu của form xử lý nút lệnh Bước 2: Thiết lập thuộc tính cho điều khiển trong cửa sổ Properties: - label1: Thuộc tính Font: kích cỡ chữ 18; Thuộc tính ForeColor: đỏ; Thuộc tính Text: “KHOA CÔNG NGHỆ THÔNG TIN” - label2: Thuộc tính Name: lblNoiDung; Thuộc tính Font: kích cỡ chữ 20; Thuộc tính Text: “ nội dung hiển thị ” - button1: Thuộc tính Name: btnHienThi Thuộc tính Text: “Hiển thị” - button2: Thuộc tính Name: btnThoat Thuộc tính Text: “Thoát” Bước 3: Viết mã lệnh cho các nút lệnh: - Sự kiện Click của nút lệnh btnHienThi: 72
  79. privatevoid btnHienThi_Click(object sender, EventArgs e) { LblNoiDung.Text = "Xin chao" } - Sự kiện Click của nút lệnh btnThoat: privatevoid btnThoat_Click(object sender, EventArgs e) { Close(); } 3.3. Điều khiển TextBox TextBox là điều khiển dùng để nhập chuỗi làm dữ liệu đầu vào cho ứng dụng hoặc hiển thị chuỗi.Người dùng có thể nhập nhiều dòng, hoặc tạo mặt nạ để nhập mật khẩu.TextBox được đặt trong nhóm Common Controls của cửa số Toolbox như hình 3.14. Điều khiển TextBox Hình 3.14: Điều khiển TextBox trong cửa sổ Properties 73
  80.  Một số phương thức thường dùng của TextBox: Bảng 3.4 : Bảng mô tả các phương thức của TextBox Phƣơng thức Mô tả Clear() Xóa tất cả chuỗi hiển thị trong TextBox Cut() Di chuyển phần nội dung bôi đen của chuỗi Past() Dán phần nội dung được chọn của chuỗi Copy() Sao chép phần nội dung bôi đen của chuỗi Undo() Khôi phục thao tác trước Select() Chọn một phần nội dung của chuỗi trong TextBox SelectAll() Chọn tất cả nội dung của chuỗi trong TextBox DeselectAll() Bỏ chọn chuỗi trong TextBox  Một số thuộc tính thường dùng của TextBox: Bảng 3.5: Bảng mô tả các thuộc tính của TextBox Thuộc tính Mô tả Name Tên của TextBox để gọi viết lệnh Text Nội dung hiển thị ban đầu khi chương trình chạy Font Chọn kiểu chữ, kích thước chữ cho TextBox ForeColor Chọn màu chữ cho TextBox BackColor Chọn màu nền cho TextBox Enable Cho phép/Không cho phép thao tác trên TextBox Mutiline Cho phép TextBox có nhiều dòng hay không PasswordChar Ký tự thay thế khi nhập vào TextBox ReadOnly Cho phép/Không cho phép sửa dữ liệu trên TextBox Visible Ẩn/ hiện TextBox TextAlign Canh lề dữ liệu trong TextBox MaxLength Quy định chuỗi Max sẽ nhập vào TextBox, mặc định là 32767 ScrollBars Các loại thanh cuộn (dọc, ngang, cả hai) WordWrap Cho phép văn bản tự động xuống dòng khi độ dài vượt quá chiều ngang của TextBox BorderStyle định kiểu đường viền cho TextBox TabIndex Chỉ định thứ tự tab của các TextBox trên form 74
  81. Focus TextBox sẵn sàng được tương tác bởi người sử dụng CanUndo Mang giá trị True hoặc False, nếu là True thì cho phép thực hiện phương thứcUndo(), mang giá trị True khi TextBoxđã thực hiện thao tác thêm, sửa hay xóa nội dung. SelectedText Lấy ra phần nội dung chuỗi được bôi đen SelectionStart Vị trí bắt đầu chọn nội dung của chuỗi SelectionLength Chiều dài chuỗi sẽ chọn trong TextBox HideSelection Mang giá trị True hoặc False, nếu là True thì không cho phép sử dụng thuộc tính SelectionStart, nếu là giá trị False thì chó phép sử dụng SelectionStart  Một số sự kiện thường dùng của TextBox: Bảng 3.6: Bảng mô tả các sự kiện của TextBox Sự kiện Mô tả KeyDown Thực hiện công việc nào đó khi một phím được nhấn xuống KeyUp Thực hiện công việc nào đó khi một phím được nhả ra KeyPress Xảy ra khi người sử dụng nhấn một phím và nhả ra, ta dùng sự kiệnnày để lọc các phím không muốn nhận như cho nhập số (0 đến 9) không cho nhập chuỗi. Mỗi sự kiện KeyPress cho ta một cặp sự kiện KeyDown và KeyUp Click Nhấp chuột vào TextBox DoubleClick Nhấp đúp chuột vào TextBox MouseEnter Chuột nằm trong vùng thấy được của TextBox MouseHover Chuột nằm trong vùng hiển thị một quãng thời gian MouseLeave Chuột ra khỏi vùng nhập liệu của TextBox MouseMove Chuột được di chuyển trên TextBox TextChanged Giá trị của thuộc tính Text bị thay đổi 75
  82. Ví dụ 3: Thiết kế form và thực hiện các yêu cầu như hình 3.15: Khi nhấp chuột trái vào nút “Thoát” sẽ thoát chương trình Nhập chuỗi cần Nhấp chuột vào nút “Tìm Kiếm” chương trình sẽ tìm tìm kiếm “chuỗi cần tìm” có trong TextBox Nội dung hay không, nếu tìm thấy sẽ hiện chuỗi tìm thấy trên MessageBox, nếu không tìm thấy sẽ hiện chuỗi “Không tìm thấy” trên MessageBox Hình 3.15: Giao diện form xử lý TextBox Hướng dẫn: Bước 1: Thiết kế form ban đầu như hình 3.16 TextBox1 TextBox2 Hình 3.16: Giao diện ban đầu của form xử lý TextBox Bước 2: Thiết lập các thuộc tính của điều khiển trong cửa sổ Properties: - label1: Thuộc tính Text = “Nội dung:” - label2: Thuộc tính Text = “Nhập chuỗi:” - textbox1: Thuộc tính Name = txtNoiDung Thuộc tính Text= “Quả cau nho nhỏ miếng trầu cay 76
  83. Này của Xuân Hương đã quệt rồi Có phải duyên nhau thì thắm lại Đừng xanh như lá bạc như vôi” Thuộc tính Multiline = true; Sử dụng chuột điều chỉnh kích thước textbox1 như hình 3.15. - textbox2: Thuộc tính Name = txtTimKiem - button1: Thuộc tính Name = btnTimKiem Thuộc tính Text = “Tìm kiếm” - button2: Thuộc tính Name = btnThoat Thuộc tính Text = “Thoát” Bước 3: Viết mã lệnh cho các nút lệnh: - Sự kiện Click của nút lệnh btnThoat: privatevoid btnThoat_Click(object sender, EventArgs e) { Close(); } - Sự kiện Click của nút lệnh btnTimKiem: privatevoid btnTimKiem_Click(object sender, EventArgs e) { int i; i=txtNoiDung.Text.IndexOf(txtchuoitk.Text); if (i >= 0) { txtNoiDung.SelectionStart = i; txtNoiDung.SelectionLength = txtchuoitk.Text.Length; MessageBox.Show(txtNoiDung.SelectedText); } else MessageBox.Show("Không tìm thấy"); } 3.4. Điểu khiể n ComboBox và ListBox ComboBoxvàListBox là hai điều khiển có nhiều điểm tương đồng, đều sử dụng để chứa dữ liệu cho phép người dùng lựa chọn. 77
  84. 3.4.1. ListBox Tại mỗi thời điểm có thể chọn một hoặc nhiều dòng dữ liệu, không cho nhập mới. Điều khiển ListBox được đặt trong nhóm Common Controls của cửa số Toolbox như hình 3.17 Điều khiển ListBox Hình 3.17: Điều khiển ListBox trong cửa sổ Properties  Một số thuộc tính thường dùng của ComboBox: Bảng 3.7: Bảng mô tả các thuộc tính của ComboBox Thuộc tính Mô tả SelectionMode Cho phép chọn một hoặc nhiều dòng dữ liệu trên ListBox, bao gồm: . One: chỉ chọn một giá trị. . MultiSimple: cho phép chọn nhiều, chọn bằng cách click vào mục chọn, bỏ chọn bằng cách click vào mục đã chọn. . MultiExtended: chọn nhiều bằng cách nhấn kết hợp với Shift hoặc Ctrl SelectedItems Được sử dụng khi SelectionModelà MultiSimple hoặc MultiExtended. Thuộc tínhSelectedItemschứa các dòng dữ liệu được chọn. SelectedIndices Được sử dụng khi SelectionModelà MultiSimple hoặc MultiExtended. Thuộc tínhSelectedItemschứa các chỉ số của các dòng dữ liệu được chọn. FormatString Chuỗi định dạng. Tất cả các mục chọn trong ListBox sẽ được định dạng theo chuỗi này. Việc 78
  85. định dạng này chỉ thực hiện khi thuộc tính FormattingEnabled được thiết lập là True FormatingEnable Mang hai giá trị True và False. Nếu là True thì cho phép các mục chọn trong ListBox có thể định dạng lại. Nếu là False thì không thể định dạng. Items Trả về các mục chứa trong ListBox DataSource Chọn tập dữ liệu điền vào ListBox. Tập dữ liệu có thể là mảng chuỗi, ArrayList, SelectedIndex Lấy chỉ số mục được chọn, chỉ số mục chọn đầu tiên là 0 SelectedItem Trả về mục được chọn SelectedValue Trả về giá trị của mục chọn nếu ListBox có liên kết dữ liệu. Nếu không liên kết dữ liệu hoặc thuộc tính ValueMember không được thiết lập thì thì giá trị thuộc tính SelectedValue là giá trị chuỗi của thuộc tính SelectedItem ValueMember Thuộc tính này chỉ định dữ liệu thành viên sẽ cung cấp giá trị cho ListBox Ví dụ 4: Xây dựng chương trình với ListBox chứa danh sách tên của các sinh viên như hình 3.18 ListBox cho Hiển thị các sinh phép chọn viên được chọn nhiều sinh trên ListBox viên thông qua MessageBox Thoát chương trình Hình 3.18: Giao diện ví dụ 4 79
  86. Hướng dẫn: Bước 1: Thiết kế giao diện ban đầu như hình 3.19 Hình 3.19: Giao diện ban đầu ví dụ 4 Bước 2: Thiết lập giá trị các thuộc tính cho điều khiển - label1: Thuộc tính Text = “Danh sách sinh viên” Thuộc tính Size = 16 - button1: Thuộc tính Text = “Hiển thị” Thuộc tính Name = btnHienThi - button2: Thuộc tính Text = “Thoát” Thuộc tính Name = btnThoat - listBox1: listBox1 chứa danh sách tên sinh viên, danh sách tên sinh viên có thể đưa vào listBox1 bằng cách thiết lập thuộc tính Items của listBox1 trong cửa sổ Properties như hình 3.20 80
  87. Hình 3.20: Thiết lập thuộc tính Items cho listBox1 Bước 3: Viết mã lệnh cho các nút lệnh: - Sự kiện Click của nút lệnh btnHienThi: privatevoidbtnHienThi_Click(object sender, EventArgs e) { string str=""; foreach(string item in listBox1.SelectedItems) { str=str+item+"; "; } MessageBox.Show(str); } - Sự kiện Click của nút lệnh btnThoat: privatevoid btnThoat_Click(object sender, EventArgs e) { Close(); } 81
  88. 3.4.2. ComboBox Mỗi lần chỉ có thể chọn một giá trị, có thể nhập mới dữ liệu vào. Điều khiển ComboBox được đặt trong nhóm Common Controls của cửa số Toolbox như hình 3.21 Điều khiển ComboBox Hình 3.21: Điều khiển ComboBox trong cửa sổ Properties  Một số thuộc tính thường dùng của ComboBox: Bảng 3.8: Bảng mô tả thuộc tính của ComboBox Thuộc tính Mô tả Text Trả về nội dung dòng dữ liệu đang hiển thị trên ComboBox DropdownStyle Quy định dạng của ComboBox, nhận một trong các giá trị: . DropDown: giá trị mặc định, có thể chọn hoặc nhập mới mục dữ liệu vào ComboBox. . Simple: hiển thị theo dạng ListBox + TextBox có thể chọn dữ liệu từ ListBox hoặc nhập mới vào TextBox. . DropDownList: chỉ cho phép chọn dữ liệu trong ComboBox DropDownHeight Thiết lập chiều cao tối đa khi sổ xuống của ComboBox DropDownWidth Thiết lập độ rộng của mục chọn trong ComboBox FormatString Chuỗi định dạng. Tất cả các mục chọn trong ComboBox sẽ được định dạng theo chuỗi này. Việc định dạng này chỉ thực hiện khi thuộc tính FormattingEnabled được thiết lập là True FormatingEnable Mang hai giá trị True và False. Nếu là True thì cho phép các mục chọn trong ComboBox có thể định dạng lại. Nếu là False thì không thể định dạng. Items Trả về các mục chứa trong ComboBox 82
  89. DataSource Chọn tập dữ liệu điền vào ComboBox. Tập dữ liệu có thể là mảng chuỗi, ArrayList, SelectedIndex Lấy chỉ số mục được chọn, chỉ số mục chọn đầu tiên là 0 SelectedItem Trả về mục được chọn SelectedText Lấy chuỗi hiển thị của mục chọn SelectedValue Trả về giá trị của mục chọn nếu ComboBox có liên kết dữ liệu. Nếu không liên kết dữ liệu hoặc thuộc tính ValueMember không được thiết lập thì thì giá trị thuộc tính SelectedValue là giá trị chuỗi của thuộc tính SelectedItem ValueMember Thuộc tính này chỉ định dữ liệu thành viên sẽ cung cấp giá trị cho ComboBox Ví dụ 5: Xây dựng chương trình với giao diện như hình 3.22 gồm ComboBox chứa danh sách 4 màu (vàng, xanh, đỏ, đen) và một Label hiển thị dòng chữ “Hoàng Sa, Trƣờng Sa là của Việt Nam”. Yêu cầu khi chọn màu trong ComboBox thì màu của dòng chữ trên Label sẽ thay đổi tương ứng. Điều khiển ComboBox Hình 3.22: Giao diện ví dụ 5 Hướng dẫn: Bước 1: Thiết kế giao diện ban đầu như hình 3.23 Hình 3.23: Giao diện ban đầu ví dụ 5 Bước 2: Thiết lập giá trị thuộc tính cho điều khiển - label1: 83
  90. Thuộc tính Text = “Chọn màu:” - button1: Thuộc tính Name = btnDoiMau Thuộc tính Text = “Đổi màu” - button2: Thuộc tính Name = btnThoat Thuộc tính Text = “Thoát” - label2: Thuộc tính Name = lblHienThi Thuộc tính Text = “Trường Sa, Hoàng Sa là của Việt Nam” - comboBox1: comboBox1chứa danh sách 4 màu gồm: Vàng, xanh, đỏ, đen. Danh sách màu này có thể đưa vào comboBox1 bằng cách thiết lập thuộc tính Items của comboBox1 trong cửa sổ Properties như hình 3.24 Hình 3.24: Thiết lập thuộc tính Items của comboBox1 Bước 3: Viết mã lệnh cho các nút lệnh: - Sự kiện Click của nút lệnh btnDoiMau: privatevoidbtnDoiMau_Click(object sender, EventArgs e) { if (comboBox1.Text == "Vàng") lblHienThi.ForeColor = Color.Yellow; if (comboBox1.Text == "Đỏ") lblHienThi.ForeColor = Color.Red; if (comboBox1.Text == "Đen") lblHienThi.ForeColor = Color.Black; if (comboBox1.Text == "Xanh") lblHienThi.ForeColor = Color.Blue; } 84
  91. - Sự kiện Click của nút lệnh btnThoat: privatevoid btnThoat_Click(object sender, EventArgs e) { Close(); } 3.4.3. Phƣơng thức và sự kiện của ComboBox và ListBox Một số phương thức và thuộc tính thường dùng của ComboBox.Items hoặc ListBox.Items: Bảng 3.9: Bảng mô tả các phương thức và thuộc tính của ComboBox.Item và ListBox.Item Phƣơng thức Mô tả Add( ) Thêm một mục vào cuối danh sách ComboBox hoặc ListBox AddRange( ) Thêm một mảng các mục Insert( i, ) Chèn thêm mục chọn vào vị trí i Count Trả về số mục chọn hiện đang có Item( i ) Trả về mục chọn ở vị trí thứ i Remove( ) Xóa mục chọn khỏi ComboBox hoặc ListBox RemoveAt( i ) Xóa mục chọn có chỉ số i khỏi ComboBox hoặc ListBox Contains( ) Trả về True nếu có mục chọn trong danh sách, trả về False nếu không có mục chọn trong ComboBox hoặc ListBox Clear() Xóa tất cả các mục chọn IndexOf( ) Trả về chỉ số mục chọn trong ComboBox hoặc ListBox, nếu không tìm thấy sẽ trả về -1  Sự kiện thường dùng của ComboBox và ListBox: Cả ComboBox và ListBox đều sử dụng sự kiện SelectedIndexChange để kiểm tra sự thay đổi mục chọn của người dùng. Ví dụ 5: Thiết kế form quản lý danh sách sản phẩm như hình 3.25. Với CboViTri là điều khiển ComboBox chứa danh sách chỉ số của danh sách sản phẩm trong ListBox Li_DSSanPham. Yêu cầu chức năng: 85
  92. - Khi nhấn nút btnThem thì sẽ thêm sản phẩm mới vào cuối danh sách trong ListBox Li_DSSanPham. - Khi nhấn nút btnThemVT thì sẽ thêm sản phẩm mới vào danh sách tại vị trí như CboVitri chỉ định. - Khi nhấn nút btnTimKiem sẽ hiển thị một MessageBox thông báo có tìm thấy sản phẩm trong danh sách không. - Khi nhấn nút btnXoa sẽ xóa sản phẩm được chọn trong danh sách. - Khi nhấn nút btnXoaDS sẽ xóa tất cả sản phẩm trong danh sách. Li_DSSanPham btnThem CboViTri btnThemVT btnTimKiem btnXoa btnXoaDS Hình 3.25: Giao diện form quản lý sản phẩm Hướng dẫn: Bước 1: Thiết kế giao diện ban đầu như hình 3.26 Hình 3.26: Giao diện ban đầu form quản lý sản phẩm Bước 2: Thiết lập thuộc tính cho điều khiển trong cửa sổ Properties như sau: - listBox1: Thuộc tính Name: Li_DSSanPham - label1: Thuộc tính Text: “Danh sách sản phẩm:” 86