Đề cương Lập trình Winform và ADO.NET

Tài liệu Đề cương Lập trình Winform và ADO.NET: 1 TRƢỜNG ĐẠI HỌC SƢ PHẠM KỸ THUẬT HƢNG YÊN KHOA CÔNG NGHỆ THÔNG TIN ĐỀ CƢƠNG HỌC PHẦN: LẬP TRÌNH WINFORM VÀ ADO.NET Hƣng Yên (Tài liệu lƣu hành nội bộ) 2 MỤC LỤC BÀI 1: TỔNG QUAN .......................................................................................................................... 4 1.1. Giới thiệu về Net Framework ............................................................. 4 1.2. Giới thiệu về Windows Form.............................................................. 5 BÀI 2: MỘT SỐ ĐIỀU KHIỂN WINFORM (1) ................................................................... 15 2.1. Label ( ) ................................................................................ 15 2.2. TextBox( ) ........................................................................ 16 2.3. Button ( ) .................................................................. 17 2.4. CheckBox ( ) ........................................................ 18 2.7. R...

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

Các file đính kèm theo tài liệu này:

  • pdf01200005_1469_1983549.pdf