Báo cáo Tìm hiểu về công nghệ .NET Compact Framework và lập trình ứng dụng trên Pocket PC

Tài liệu Báo cáo Tìm hiểu về công nghệ .NET Compact Framework và lập trình ứng dụng trên Pocket PC: Tìm hiểu về công nghệ .NET Compact Framework và lập trình ứng dụng trên Pocket PC. Information Mục Lục Lời Nói Đầu: Chương 1 : Thiết lập môi trường phát triển ứng dụng 1.1 Smart Device Extension và .NET Compact Framework 1.2 Những thiết bị phi chuẩn Chương 2:Thiết kế những ứng dụng GUI băng Windows Forms. 2.1 Tìm hiểu những điều khiển không được hỗ trợ trong .NET Compact Framework 2.2 Những hàm System.Windows.Forms không được hỗ trợ trong .NET Compact Framework. 2.3 Làm việc với cửa sổ Form Designer của Visual Studio .NET 2.4 Tìm hiểu về các nền tảng khác nhau của Windows Forms 2.5 Làm việc với Control của Form. 2.6 Điều khiển Button 2.7 Sử dụng điều khiển TextBox 2.8 Sử dụng điều khiển Label 2.9 Điều khiển RadioButton 2.10 Sử dụng điều khiển CheckBox 2.11. Sử dụng điều khiển ComboBox 2.12 Sử dụng điều khiển ListBox 2.13 Các điều khiển khác Chương 3: Tìm hiểu ADO.NET trên .NET Compact Framework 3.1 Giới thiệu ADO.NET trên .NET Compact Framework 3.2. Lưu dữ liệu với Data...

doc96 trang | Chia sẻ: hunglv | Lượt xem: 1246 | Lượt tải: 0download
Bạn đang xem trước 20 trang mẫu tài liệu Báo cáo Tìm hiểu về công nghệ .NET Compact Framework và lập trình ứng dụng trên Pocket PC, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tìm hiểu về công nghệ .NET Compact Framework và lập trình ứng dụng trên Pocket PC. Information Mục Lục Lời Nói Đầu: Chương 1 : Thiết lập môi trường phát triển ứng dụng 1.1 Smart Device Extension và .NET Compact Framework 1.2 Những thiết bị phi chuẩn Chương 2:Thiết kế những ứng dụng GUI băng Windows Forms. 2.1 Tìm hiểu những điều khiển không được hỗ trợ trong .NET Compact Framework 2.2 Những hàm System.Windows.Forms không được hỗ trợ trong .NET Compact Framework. 2.3 Làm việc với cửa sổ Form Designer của Visual Studio .NET 2.4 Tìm hiểu về các nền tảng khác nhau của Windows Forms 2.5 Làm việc với Control của Form. 2.6 Điều khiển Button 2.7 Sử dụng điều khiển TextBox 2.8 Sử dụng điều khiển Label 2.9 Điều khiển RadioButton 2.10 Sử dụng điều khiển CheckBox 2.11. Sử dụng điều khiển ComboBox 2.12 Sử dụng điều khiển ListBox 2.13 Các điều khiển khác Chương 3: Tìm hiểu ADO.NET trên .NET Compact Framework 3.1 Giới thiệu ADO.NET trên .NET Compact Framework 3.2. Lưu dữ liệu với DataSet 3.3 Tìm hiểu về các ràng buộc dữ liệu 3.4 Thiết lập cho các trường tự động tăng giá trị 3.5. Mô hình dữ liệu quan hệ với DataSet 3.6 Tạo các khung ràng buộc của dữ liệu với một DataView Chương 4: Lập trình với Microsoft SQL Server CE 4.1 Tìm hiểu các tính chất hỗ trợ bởi Microsoft SQL Server 2000 Windows CE Edition 4.2 Tạo CSDL Microsoft SQL Server CE 4.3 Thêm cấu trúc vào một CSDL Microsoft SQL Server CE 4.4 Lưu trữ (Populating) CSDL Microsoft SQL Server CE 4.5 Lấy dữ liệu bằng SqlCeDataReader 4.6 Lọc một DataSet bằng SqlCeDataAdapte 4.7 Cập nhật CSDL Microsoft SQL Server CE sử dụng SqlCeDataAdapter 4.8 Đối tượng SqlCommand với SqlCeCommandBuilder Chương 5: Tài Liệu Tham Khảo Mục Lục Lời Nói Đầu Như chúng ta thấy, hiện nay các thiết bị di động ngày càng trở nên đa dạng và rất phong phú, nó bao gồm rất nhiều loại máy tính xách tay và các loại máy điện thoại di động khác nhau. Những chiếc máy tính xách tay hay những chiếc điện thoại di động đang ngày càng trở nên rẻ hơn, thiết kế cải tiến hơn, kiểu dáng nhỏ gọn và đẹp mắt hơn, chúng có nhiều tính năng tiện dụng hơn. Những thiết bị di động đang trở nên càng ngày càng lôi cuốn nhiều công ty và cá nhân sử dụng hơn. Mặt khác những thiết bị này rất hữu dụng và tiện lợi. Cũng chính vì nhu cầu đó, việc phát triển phần mềm để chạy trên những thiết bị di động này cũng ngày càng yêu cầu những kỹ thuật đặc biệt hơn Sự phát triển những ứng dụng cho các thiết bị di động sẽ cần đến những kỹ năng đặc biệt. Những thiết bị cầm tay ngày càng được thiết kế với kích thước nhỏ gọn, xây dựng những ứng dụng tốt hơn, phù hợp với nhu cầu tự nhiên của con người. Vì vậy, với .NET Compact Framework và Smart Device Extensions (SDE) của Visual Studio NET, Microsoft đã cung cấp một kỹ thuật phát triển phần mềm thích hợp cho các loại thiết bị di động và những người thiết kế các thiết bị di động. Và sau đây ta sẽ tìm hiểu về .NET Compact Framework và Smart Device Extensions. Tìm hiểu về công nghệ .NET Compact Framework và lập trình ứng dụng trên Pocket PC. Sau đây chúng ta sẽ tìm hiểu về công nghệ .NET Compact Framework và lập trình ứng dụng trên Pocket PC trên nền Windows mobile. Trong tài liệu này, các ví dụ được triển khai bằng ngôn ngữ lập trình C#, trong Visual Studio.NET 2003. Chương 1 : Thiết lập môi trường phát triển ứng dụng 1.1 Smart Device Extension và .NET Compact Framework 1.1.1 Giới thiệu về .NET Compact Framework - .NET Compact Framework là nền tảng dữ liệu cho các ứng dụng Visual Studio .NET được phát triển cho các thiết bị di động sử dụng hệ điều hành Windows CE hoặc Windows Mobile - .NET Compact Framework là một thư viện lớp phong phú, cung cấp một API đồng dạng mà những người phát triển có thể dung cả C#, Visual Basic NET, và cả những ngôn ngữ trong tương lai sẽ được hỗ trợ .NET Compact Framework - .NET Compact Framework gồm những lớp truy nhập dữ liệu rất đa dạng và rộng, những lớp thao tác XML, có một tập hợp những kiểu dữ liệu cơ bản phong phú, có sự hỗ trợ nối mạng dễ sử dụng hơn, và..v..v… - .NET Compact Framework 2.0 là nền tảng cho 1 số ứng dụng cho PPC được phát triễn trên code Visual Studio .NET. .NET Compact Framework là một phiên bản thu nhỏ của .NET Framework được sử dụng để tạo, xây dựng, gỡ lỗi và triển khai các ứng dụng chạy trên .NET Compact Framework trong các PDA, điện thoại di động và các thiết bị thông minh khác. NET Compact Framework sử dụng một số những thư viện lớp thông thường giống như .NET Framework và ngoài ra còn sử dụng một vài thư viện được thiết kế đặc biệt dành cho những thiết bị di động như Windows CE InputPanel. .NET Compact Framework là nền tảng của Microsoft để phát triển các ứng dụng di động, hỗ trợ khả năng khai thác sức mạnh của các dịch vụ web trên thiết bị di động. Ngoài ra, lập trình viên có thể tận dụng những tính năng cao cấp của Visual Studio "Everett" để xây dựng các ứng dụng hữu ích cho doanh nghiệp một cách nhanh chóng. Smart Device Extensions, một phần mở rộng cho IDE của Visual Studio .NET, cung cấp các chức năng giúp đơn giản hoá việc lập trình ứng dụng di động. Sự khác nhau giữa .NET Compact Framework và .NET Framework: .NET Compact Framework là một phiên bản thu nhỏ của .NET Framework. .NET Compact Framework và .NET Framework, tuy cả 2 đều là nền tảng của Visual Studio .NET,nhưng: *.NET Compact Framework: phát triển chủ yếu cho các ứng dụng của Windows Mobile. Khi cài đặt .NET Compact Framework (phiên bản giành cho Windows) thì chương trình cũng sẽ tự động cập nhật phiên bản mới cho điện thoại (nếu phiên bản cài đặt là bản mới hơn bản được tích hợp sẵn của hệ điều hành WM). Và .NET compact framwork cho Pocket PC giới hạn hơn và chỉ có khoảng 2.5 M * .NET Framework là nền tảng phát triển các ứng dụng cho PC. 1.1.2 Những yêu cầu về hệ thống. Smart Devices Extensions (Mở rộng những thiết bị thông minh) là môi trường phát triển tích hợp (IDE) thông qua mục đích của những người thiết kế .NET Compact Framework. Nó bao gồm phiên bản Visual Studio .NET 7.1 hoặc các phiên bản về sau, Enterprise Developer và Enterprise Architect Editions. Để chạy Visual Studio .NET 7.1 Enterprise Developer hay Enterprise Architect, bạn cần một hệ thống máy tính với những yêu cầu tối thiểu được phác thảo trong bảng 1.1. Bảng 1.1. Những yêu cầu hệ thống trong Visual Studio .NET 2003 Vùng Yêu cầu Operating system and RAM Windows 2000 Professional; 96MB RAM, đề nghị 128MB Windows 2000 Server; 192MB RAM, đề nghị 256MB. Windows XP Professional; 192MB RAM, đề nghị 256MB. Windows XP Home; 96MB RAM, đề nghị 128MB Windows .NET Server 2003; 192MB RAM, đề nghị 256MB Hard disk space Tối thiểu 900MB trên ổ chứa hệ điều hành và khoảng 4.1GB để cài Microsoft Visual Studio.NET Processor speed Tối thiểu Pentium II 450MHz hoặc tương đương; Pentium III 600MHz hoặc lớn hơn Device connectivity ActiveSync 3.5 hoặc lớn hơn Ngoài ra, ta cần có một thiết bị được hỗ trợ để chạy những chương trình. .NET Compact Framework tương thích với mọi thiết bị có khả năng chạy hệ điều hành Pocket PC. Việc truy nhập Smart Device Extensions xảy ra tự động khi bạn tạo ra một ứng dụng mới cho một Pocket PC hay thiết bị Windows CE hoặc khi bạn mở một Pocket PC được tạo ra trước đó hay một ứng dụng Windows CE. 1.1.3 Sử dụng Smart Device Extensions Cách đơn giản nhất để phát triển .NET Compact Framework là sử dụng Smart Device Extensions (những mở rộng thiết bị thông minh) trong Visual Studio .NET 7.1. Để đơn giản cho một mở rộng của Visual Studio 7.1, thì Smart Device Extensions giới thiệu những kiểu dự án mới, cho phép chúng ta chạy trên Windows CE, những Thiết bị hỗ trợ .NET Compact Framework, như Pocket PC. Điều này có nghĩa là sử dụng Smart Device Extensions để phát triển những ứng dụng cho Windows CE dễ dàng như việc phát triển những ứng dụng cho Windows 2000 hay XP. Nếu bạn đã làm một ứng dụng bằng việc sử dụng những phiên bản trước đây của Visual Basic, thì bạn cũng không phải lo lắng gì với Smart Device Extensions của Visual Studio. Smart Device Extensions đủ thông minh để biên dịch ứng dụng của bạn. 1.1.4 Tạo một ứng dụng mới cho những thiết bị Pocket PC Cách dễ dàng nhất để giới thiệu Smart Device Extensions là bằng ví dụ. Chúng ta sẽ tạo ra một chương trình ứng dụng đơn giản có tên là “Hello World” bằng ngôn ngữ C#. Chúng ta sẽ thực hiện theo những bước sau: - Bước 1: Khi Visual Studio .NET bắt đầu chạy, nó sẽ hiển thị một của sổ Start Page, như hình 1. Để tạo ra một ứng dụng mới, bạn kích vào nút New Project nằm ở gần đáy của màn hình; Ta sử dụng thực đơn kéo xuống bằng việc lựa chọn File -> New->, Project; hay sử dụng tổ hợp phím bấm Ctrl+ Shift+ N. Hình 1: Của sổ Start Page hiển thị khi khởi động chương trình Visual Studio. Bước 2: Sau khi chúng ta kích vào New Project, một hộp thoại hiện ra, nó hiển thị kiểu của project. Chúng ta chọn thư mục Visual Basic Projects và mẫu Smart Device Application, như hình 2. Bạn sẽ đặt một tên và chỉ vị trí để lưu ứng dụng mới và tiếp theo là kích nút OK. Hình 2: Hộp thoại tạo một Visual Basic Smart Device Application - Bước 3: Hộp thoại tiếp theo, như hình 3 Hình 3: chọn một nền đích và một mẫu ứng dụng - Bước 4: Sau khi chúng ta đã lựa chọn như hình 3 và kích OK, Visual Studio tự động kích hoạt Smart Device Extensions và đưa ra những trình thiết kế mẫu, như hình 4. Hình 1.5: Trình thiết kế Forms hiện ra sau khi một dự án được tạo. - Bước 5: Bên trái của khung thiết kế Forms là một nút nhỏ có tên là Toolbox. Việc kích nút này sẽ đưa ra hộp Toolbox, như được minh hoạ trong hình 5. Hình 5: Hiển thị hộp ToolBox. - Bước 6: Mỗi mục trong Toolbox là một điều khiển sẵn có để những người thiết kế dùng trong .NET Compact Framework. Hầu hết điều khiển đều có liên quan đến Winforms. Cho hướng dẫn này, chúng ta sẽ lựa chọn một TextBox, kéo nó lên Form, và tiếp theo, lại lựa chọn một Button và kéo nó lên Form. Hình 6 cho thấy kết quả. Hình 6: Hiển thị kết quả sau khi kéo TextBox và Button vào Form -Bước 7: Bây giờ ta kích kép vào nút Button1, và IDE đưa ra code với con trỏ nhấp nháy ở ngay phương thức Button1_click. Bất cứ code nào được nhập vào đều được thực hiện khi ta kích vào nút Button1. Bây giờ chúng ta sẽ nhập một vài code Visual Basic như hình 7. Hình 7: Hiển thị code sau khi kích vào nút button trên Form - Bước 8. Cách làm này rất giống cách làm cho máy để bàn, và nó là điểm của Smart Device Extensions và .NET Compact Framework. Dự án lúc này đã sẵn sàng để biên dich và chạy trên thiết bị. Để chạy ứng dụng trên thiết bị, chọn Debug, Start Without Debugging. Đầu tiên Visual Studio sẽ biên dịch mã nguồn và sau đó đưa ra hộp thoại Deploy Smart Device Application, như trong hình 8. Hình 8: Trước khi triển khai một ứng dụng cho một thiết bị, Visual Studio cho thấy hộp thoại triển khai. -Bước 9: Ta sẽ chọn một trong các bộ mô phỏng có trong hình 8 để chạy ứng dụng. Trong ứng dụng này ta chọn Pocket PC 2002 Emulator. Nếu muốn chạy thử trên các thiết bị thực, chúng ta chọn Pocket PC Device nhưng phải đảm bảo rằng thiết bị đã được kết nối thông qua đường ActiveSyne trước khi triển khai ứng dụng trên thiết bị. Sau đó chọn Deploy. - Bước 10: Visual Studio cài đặt .NET Compact Framework và khởi chạy ứng dụng của bạn trên thiết bị. Nếu bạn kích vào nút Button, bạn sẽ nhìn thấy kết quả của ứng dụng như hình 9. Hình 9: Thiết bị mô phỏng chạy ứng dụng Hello World. 1.2 Những thiết bị phi chuẩn .NET Compact Framework có thể chạy trên rất nhiều các thiết bị phần cứng chạy hệ điều hành Windows CE. Bảng 1.2 cho chúng ta thấy các bộ xử lý được hỗ trợ bởi .NET Compact Framework và các hệ điều hành hỗ trợ cho các bộ xử lý. .NET Compact Framework được lưu trữ như một file CAB trên Desktop. Chỉ có một file CAB duy nhất cho mỗi hệ điều hành và kiểu bộ xử lý mà .NET Compact Framework hỗ trợ. Smart Device Extensions đưa file CAB phù hợp vào thiết bị khi nó xác định thiết bị không cài đặt .NET Compact Framework. Tên CPU Phiên bản hệ điều hành hỗ trợ Intel ARM 4 Pocket PC 2000, 2002, 2003, and WinCE 4.1 hoặc mới hơn Intel ARM 4i Pocket PC 2000, 2002, 2003, and WinCE 4.1 hoặc mới hơn Hitachi SH3 Pocket PC 2000, 2002, 2003, and WinCE 4.1 hoặc mới hơn Hitachi SH4 Pocket PC 2003 and WinCE 4.1 hoặc mới hơn Intel 80x86 Pocket PC 2000, 2002, 2003, and WinCE 4.1 hoặc mới hơn MIPS 16 Pocket PC 2000, 2002, 2003, and WinCE 4.1 hoặc mới hơn MIPS II Pocket PC 2000, 2002, 2003, and WinCE 4.1 hoặc mới hơn MIPS IV Pocket PC 2000, 2002, 2003, and WinCE 4.1 hoặc mới hơn Bảng 1.2: Bộ xử lý và hệ điều hành được hỗ trợ bởi .NET Compact Framework Tất cả các thiết bị Pocket PC chạy hệ điều hành Pocket PC version 2003 hoặc mới hơn đều có .NET Compact Framework trong ROM. Nếu chúng ta không thể triển khai hoặc gỡ lỗi ứng dụng trên các thiết bị, trong phần này chúng ta sẽ học cách làm thế nào để Smart Device Extensions kết nối với các thiết bị để gỡ lỗi, triển khai và thảo luân một vài vấn đề liên quan. Có ba mức hỗ trợ phi chuẩn: - Hỗ trợ đầy đủ triển khai và gỡ lỗi thông thường, mức hỗ trợ này có nghĩa rằng IDE có thể triển khai hệ nhị phân tới thiết bị và gỡ lỗi mã nguồn đang chạy trên thiết bị. Chỉ hỗ trợ triển khai: có nghĩa rằng IDE có thể chỉ triển khai hệ nhị phân tới thiết bị nhưng không thể gỡ lỗi mã chạy trên thiết bị được. - Chỉ hỗ trợ đích (Target). Mức hỗ trợ này có nghĩa là chúng ta có thể phát triển ứng dụng của chúng ta trong Visual Studio, nhưng chúng ta phải cài đặt Compact Framework trên thiết bị và sao chép vào thiết bị. * Kết nối Visual Studio với các thiết bị Để thiết lập giao tiếp Visual Studio với thiết bị, chúng ta làm theo các bước sau: + Bước 1: chọn Tools -> Options trong Visual Studio. + Bước 2: kích đúp trên mục Device Tools và chọn Devices. Xem hình 10 Hình 10: Sử dụng hộp thoại kết nối thiết bị để chọn kiểu thiết bị muốn kết nối. + Bước 3: Chọn nền tảng Pocket PC hay Windows CE. + Bước 4: Chọn kiểu thiết bị mà chúng ta muốn triển khai ứng dụng trên đó. Hình 10 cho phép chọn Emulator hoặc thiết bị Pocket PC. + Bước 5: Lựa chọn cách thức truyền tin được dụng. Thiết bị Pocket PC có hai lựa chọn là: kết nối TCP và IRDA. Kết nối TCP Connect Transport có nghĩa là thiết bị desktop sẽ kết nối với ConmanClient.exe trên thiết bị bằng kết nối TCP. Kết nối IRDA Transport sử dụng IRDA trên thiết bị để kết nối. Điều này rất hữu ích khi máy tính của chúng ta là laptop có cổng IRDA. + Bước 6: Nếu chọn TCP Connect Transport, sau đó chúng ta có thể thay đổi bằng cách chọn nút Configure…sau đó sẽ nhận được như hình 11. Hình 11: TCP Connect Transport cho phép thiết lập kết nối tới thiết bị TCP. + Bước 7: Hộp thoại như hình 11 cho phép chúng ta thiết lập địa chỉ IP cho thiết bị. Nếu thiết bị nối kết bằng ActiveSyne, Visual Studio có thể tự động điều khiển nhận ra địa chỉ. Chúng ta có thể lựa chọn sử dụng số hiệu cổng khác với cổng 5656. Để không sử dụng cổng mặc định, bạn phải tự cấu hình ConmanClient.exe trên thiết bị. Chương 2:Thiết kế những ứng dụng GUI băng Windows Forms. .NET Compact Framework cung cấp rất nhiều chức năng để xây dựng giao diện đồ hoạ cho ứng dụng của bạn. Tuy nhiên, những chức năng này là chỉ một tập con của tập các chức năng mà .NET Framework đã cung cấp. Trước khi giới thiệu những điều khiển mà .NET Compact Framework hỗ trợ, thì chúng ta hãy tìm hiểu một số điều khiển mà nó không hỗ trợ. 2.1 Tìm hiểu những điều khiển không được hỗ trợ trong .NET Compact Framework Danh sách sau đây chứa những control mà không được hỗ trợ trên .NET Compact Framework. CheckedListBox ColorDialog ErrorProvider FontDialog GroupBox HelpProvider LinkLabel NotificationBubble NotifyIcon All Print controls RichTextBox Splitter 2.2 Những hàm System.Windows.Forms không được hỗ trợ trong .NET Compact Framework. Ngoài những điều khiển không được hỗ trợ, .NET Compact Framework cũng không có một số hàm để cung cấp cho các điều khiển này. Danh sách sau đây đưa ra những hàm .NET Compact Framework không hỗ trợ. AcceptButton CancelButton AutoScroll Anchor Multiple Document Interface (MDI) KeyPreview TabIndex TabStop Drag and drop All printing capabilities Hosting ActiveX controls 2.3 Làm việc với cửa sổ Form Designer của Visual Studio .NET Trình thiết kế Form Visual Studio .NET cho phép chúng ta thiết kế giao diện người dùng cho ứng dụng một cách trực quan bằng những điều khiển được kéo lên Form ứng dụng. Mỗi một control được kéo lên form, chúng ta có thể nhìn thấy và định vị trí cho những control đó, và đặt những thuộc tính cho các control đó thông qua cửa sổ Properties, và tạo ra những bộ xử lý sự kiện cho những sự kiện của những control. 2.3.1 Cửa sổ thiết kế Forms Khi chúng ta tạo ra một dự án Smart Device Extension (SDE) mà là một ứng dụng Windows, thì Visual Studio .NET sẽ mở dự án trong khung Designer. Ngoài ra, chúng ta cũng có thể chọn Designer từ menu View để đưa dự án vào khung Designer. Form Designer thường là cửa sổ nằm ở giữa của môi trường Visual Studio .NET. Hình 2.1 hiển thị Form Designer của một dự án SDE Pocket PC trong khung thiết kế Designer. Chú ý thành phần mainMenu1 ở đáy của cửa sổ Designer. Hình 2.1: Khung Designer của SDE Pocket PC. Chú ý: Khi Form Designer được sử dụng để xây dựng một ứng dụng, phương thức InitializeComponent chứa đựng mã nguồn để xây dựng một giao diện người dùng của ứng dụng. Mã nguồn này có ảnh hưởng lớn đến quá trình thực thi nếu form của chúng ta chứa vài control được lồng vào nhau. Chẳng hạn, nếu có một panel được đặt trên một form và panel chứa vài control, thì panel cần phải được thêm vào form trước, sau đó những control sẽ được thêm vào panel. 2.3.2 Cửa sổ ToolBox. Cửa sổ ToolBox chứa tất cả những control của .NET Compact. Việc thêm một control cho một ứng dụng ở thời điểm thiết kế rất dễ dàng, ta chỉ việc kéo control từ hộp ToolBox và thả nó trên form của ứng dụng trong cửa sổ Form Designer. Hình 2.2 minh hoạ ToolBox cho một dự án SDE Pocket PC. Hình 2.2: Cửa sổ ToolBox của một dự án SDE Pocket PC. 2.3.3 Của sổ Properties Cửa sổ Properties chứa tất cả những đặc tính của control hiện thời đang được chọn trong cửa sổ Form Designer. Bạn có thể thay đổi những thuộc tính này bởi việc gõ những giá trị vào trong điều khiển TextBox bên cạnh tên thuộc tính. Nếu thuộc tính có một số giới hạn giá trị, thì một cái hộp thả xuống được hiển thị bên cạnh tên thuộc tính mà chứa những giá trị có thể xảy ra cho thuộc tính. Cuối cùng, nếu giá trị của thuộc tính là một tập hợp của các đối tượng hay một đối tượng phức tạp, ở đó có thể là một dấu ba chấm được định vị bên cạnh tên thuộc tính. Việc kích vào dấu ba chấm này sẽ hiển thị ra một hộp thoại cho phép bạn tự nhập thêm giá trị của thuộc tính. Hình 2.3 hiển thị cửa sổ Properties khi một TextBox được lựa chọn. Hình 2.3: Cửa sổ Properties của một điều khiển TextBox. Adding Events Handlers (Thêm bộ xử lý sự kiện) Khi một control được thao tác ở tại thời điểm đang thực thi, nó sẽ xuất hiện một sự kiện để thông báo ứng dụng mà trạng thái của điều khiển đang thay đổi. Để xử lý một sự kiện được đưa ra bởi một control, đầu tiên bạn phải tạo ra một phương thức chứa mã để thực hiện khi sự kiện được dùng. Tiếp theo bạn gắn phương thức cho sự kiện được công bố của điều khiển. Điều này có thể được làm thông qua cửa sổ Properties. Của sổ Properties liệt kê những sự kiện mà được đưa ra bởi control. Kích vào nút Events tại vị trí gần trên cùng của cửa sổ Properties, nó sẽ liệt kê ra những sự kiện. Hình 2.4 hiển thị cửa sổ Properties, va nó đang hiển thị sự kiện của control Button. Hình 2.4: Của sổ Properties hiển thị những sự kiện của control Button. Ngoài ra, chúng ta cũng có thể thêm một sự kiện xử lý bằng cách kích đúp lên tên sự kiện. Việc làm này sẽ chuyển dự án đến khung viết code. Mã để viết bộ xử lý sự kiện cho control cũng tự động được phát sinh. Chúng ta có thể tìm thấy mã này trong phương thức InitializeComponent của lớp Form của ứng dụng. 2.4 Tìm hiểu về các nền tảng khác nhau của Windows Forms Những dự án Smart Device Extensions (SDE) có thể chọn một trong hai hệ điều hành: hệ điều hành Pocket PC hay là hệ điều hành Windows CE .NET. Hai nền tảng này có APIs giao diện người dùng khác nhau. Một dự án SDE xử lý điều này bằng cách gọi những thư viện khác nhau trên mỗi nền tảng. 2.4.1 Tìm hiểu những nền tảng Windows CE .NET Những dự án Windows CE .NET cũng tương tự như những dự án ứng dụng .NET Framework thông thường trên Windows. Đầu tiên, khi mới bắt đầu tạo dự án thì trong form thiết kế có 3 nút, đó là: nút minimize, nút maximize và nút close xuất hiện trong cái hộp điều khiển của ứng dụng, chúng cũng giống như trong đối tượng Form của..NET Framework. Bạn có thể loại bỏ cái hộp điều khiển từ form bằng cách đặt thuộc tính của ControlBox là false. Bạn có thể loại bỏ nút minimize, và nút maximize bằng cách đặt thuộc tính của MinimizeBox và MaximizeBox là false.. Khi một form ứng dụng của Windows CE .NET được tạo ra bằng trình thiết kế Visual Studio .NET, thì kích thước của nó được tự động đặt ra là 640 X 450. Bạn có thể thay đổi thuộc tính size này nếu nó không thích hợp cho ứng dụng của bạn. Mặc dù lớp form trình bày thuộc tính FormBorderSytle, nhưng việc đặt thuộc tính của Sizable sẽ không ảnh hưởng đến đường viền của cửa sổ. Trong Windows CE .NET thì không có ứng dụng nào thay đổi kích thước. Nó có thể chỉ thu nhỏ, làm phóng to cực đại màn hình, hay là theo kích cỡ của thuộc tính size. 2.4.2 Tìm hiểu nền tảng Pocket PC Những ứng dụng trên Pocket PC lệch xa hơn so với những dự án của ứng dụng Windows .NET Framework thông thường. Đầu tiên, khi mới bắt đầu tạo dự án một đối tương MainMenu luôn luôn được thêm vào một ứng dụng Pocket PC. Bạn có thể loại bỏ thực đơn này, nhưng việc làm này sẽ gây ra một ngoại lệ, và nó sẽ được đưa vào khi tương tác với Soft Input Panel (SIP). SIP là một sự thi hành phần mềm của bàn phím QWERTY. Cửa sổ ToolBox của Visual Studio .NET chứa một điều khiển InputPanel. Trên Pocket PC, điều khiển này cho phép bạn tương tác với SIP. InputPanel cho phép bạn tăng và giảm SIP. Ngoài ra, InputPanel sẽ thông báo cho ứng dụng của bạn khi SIP đã được cho phép. Một điều cần chú ý là form của bạn phải có một control MainMenu trên nó và trong control InputPanel để được thêm vào form. Nếu không có control MainMenu trên form thì một ngoại lệ sẽ được đưa vào ở thời điểm đang chạy khi bạn cố gắng làm hiện rõ InputPanel Những ứng dụng Pocket PC phải bám sát vào những hướng dẫn và những nguyên tắc nhất định. Nguyên tắc đầu tiên là chỉ có một trường hợp của một ứng dụng đang chạy tại một thời điểm. Ở ngay thời điểm chạy, .NET Compact Framework sẽ bảo đảm chức năng này, như vậy không cần viết mã mà vẫn bảo đảm rằng chỉ một trường hợp của ứng dụng của bạn đang chạy. Nguyên tắc thứ hai là mỗi một lần một ứng dụng đang chạy, người sử dụng không nên đóng ứng dụng lại. Những trạng thái nguyên tắc mà ứng dụng cần phải lưu giữ bất kỳ dữ liệu nào, giải thoát cho bất kỳ tài nguyên nào, và ngắt kết nối bất kỳ kết nối nào (ví dụ như những kết nối cơ sở dữ liệu) khi nó ngừng hoạt động. Nếu ứng dụng được bắt đầu chạy lần nữa, thì nó sẽ được kích hoạt bởi OS. Khi nó được kích hoạt, ứng dụng cần phải có những tài nguyên định vị đúng (reallocate resources) và reestablish (thiết lập chính xác) bất kỳ kết nối nào. Ứng dụng sẽ được thông báo khi nó được kích hoạt hay không hoạt động bởi các sự kiện Form.Activate và Form.Deactivate. Chú ý, những sự kiện Activate và Deactivate không được liệt kê trong Properties Designer, vì vậy bạn phải tự viết và gán những sự kiện này. 2.4.3 Kết hợp một Icon (biểu tượng) với ứng dụng Một ứng dụng chưa thật sự hoàn thiện khi nó chưa có biểu tượng của nó. Việc kết hợp một biểu tượng với một ứng dụng có thể được thông qua Visual Studio .NET bằng cách mở hộp thoại Property Pages dự án. Sau đó lựa chọn General ở dưới folder Common Properties. Tiếp theo kích vào dấu ba chấm bên cạnh thuộc tính Application Icon. Việc này sẽ hiển thị OpenFileDialog. Xác định vị trí biểu tượng trong hộp thoại. 2.5 Làm việc với Control của Form. Điều khiển Form là nơi chứa toàn bộ các điều khiển của ứng dụng. Lớp form có vài thuộc tính mà gây ra cho form hoạt động khác nhau phụ thuộc vào nền tảng đích. 2.5.1 Tìm hiểu tác động của thuộc tính FormBorderStyle Thuộc tính FormBorderStyle xác định kiểu đường viền của Form. Giá trị mặc định cho đặc trưng này là FormBorderStyle.FixedSingle. Trên Pocket PC, việc đặt thuộc tính cho FormBorderStyle.None tạo ra một form không có đường viền và không có thanh tiêu đề. Kiểu này của form có thể được thay đổi kích thước và di chuyển trong mã nhưng không phải bởi người sử dụng. Đặt thuộc tính FillBorderStyle.FixedSingle hay bất kỳ giá trị nào khác sẽ tạo ra một form mà chiếm toàn màn hình, và form sẽ không di chuyển hay thay đổi kích thước được. Trên Windows CE .NET, đặt thuộc tính FormBorderStyle.FixedDialog hay FormBorderStyle.None sẽ tạo ra một form không có viền hay thanh tiêu đề. Form sẽ di chuyển và thay đổi kích thước chỉ thông qua mã. Đặt thuộc tính FormBorderStyle.FixedSingle hay mọi giá trị khác sẽ tạo ra một form được đo cỡ cho thuộc tính size với một đường viền và một thanh tiêu đề. Form chỉ được thay đổi kích thước hay di chuyển thông qua mã, và người sử dụng sẽ có khả năng để di chuyển form. 2.5.2 Sử dụng thuộc tính ControlBox Thuộc tính ControlBox của form xác định xem hộp điều khiển có được hiển thị hay không. Sự Thiết đặt thuộc tính ControlBox là true sẽ hiển thị hộp điều khiển. Đặt thuộc tính là false thì sẽ ẩn hộp điều khiển đi. 2.5.3 Tìm hiểu các thuộc tính MinimizeBox và MaximizeBox Trên Pocket PC thì hộp điều khiển chỉ chứa nhiều nhất một nút, hoặc là nút minimize có dán nhãn là X, hoặc là nút close gắn nhãn là OK. Trên Windows CE .NET thì hộp điều khiển có thể chứa cả ba nút: nút minimize, nút maximize, và nút close. Tính rõ ràng của những nút này được kiểm soát bởi những thuộc tính MinimizeBox và MaximizeBox. Bảng 2.1 mô tả những giá trị có thể xảy ra của thuộc tính MinimizeBox và những tác dụng của chúng trên mỗi nền tảng đích. Bảng 2.2 mô tả những thuộc tính tương tự cho MaximizeBox Bảng 2.1: Mô tả những giá trị có thể xảy ra của thuộc tính MinimizeBox và những tác dụng của chúng trên mỗi nền tảng đích. PROPERTY VALUE POCKET PC APPLICATION WINDOWS CE .NET APPLICATION True Nút X (minimize) trong thanh tiêu đề Nút minimize truyền thống của Windows trong thanh tiêu đề False Nut OK (close) trong thanh tiêu đề Không có nút minimize trong thanh tiêu đề. Bảng 2.2 mô tả những giá trị có thể xảy ra của thuộc tính MaximizeBox và những tác dụng của chúng trên mỗi nền tảng đích. PROPERTY VALUE POCKET PC APPLICATION WINDOWS CE .NET APPLICATION True Không có tác dụng Nút maximize truyền thống của Windows trong thanh tiêu đề. False Không có tác dụng Không có nút maximize trong thanh tiêu đề. . 2.5.4. Tìm hiểu thuộc tính WindowsState Thuộc tính WindowsState xác định trạng thái hiện rõ ban đầu của cửa sổ. Thuộc tính này chỉ có thể được thiết lập cho FormWindowState.Normal hay FormWindowState.Maximized. Bảng 2.3 mô tả giá trị và tác dụng của nó trên một ứng dụng được chạy trên cả hai nền tảng đích. Bảng 2.3: Mô tả những giá trị có thể xảy ra của thuộc tính WindowState và những tác dụng của chúng trên mỗi nền tảng đích. FormWindowState MEMBER NAME POCKET PC APPLICATION WINDOWS CE .NET APPLICATION Normal Ứng dụng sẽ chiếm toàn bộ màn hình của desktop trừ một vùng của thanh start menu và một vùng của thanh main menu. Ứng dụng có kích thước theo thuộc tính Size Maximize Ứng dụng chiếm toàn bộ màn hình, nó sẽ ẩn thanh start menu, nhưng thanh main menu vẩn hiển thị Ứng dụng sẽ chiếm toàn bộ màn hình desktop 2.5.5. Tìm hiểu thuộc tính Size Thuộc tính size xác định kích thước của cửa sổ ứng dụng. Nó phụ thuộc vào giá trị của thuộc tính FormBorderStyle, ứng dụng có thể lờ đi giá trị của thuộc tính size hoặc lờ đi việc đưa ra cho ứng dụng một kích thước theo lý thuyết. Trên Pocket PC, thì chỉ có thuộc tính size hợp lệ mới được đánh giá, FormBorderStyle phải được thiết lập từ FormBorderSytle.None. Trên Windows CE, thuộc tính size luôn luôn được đánh giá. 2.5.6 Thiết đặt Location (vị trí) của Form bằng cách sử dụng thuộc tính Location. Thuộc tính Location xác định vị trí ở góc trên, bên trái của của form. Trên Pocket PC thuộc tính Location không có tác dụng trừ khi thuộc tính FormBorderSytle thiết đặt là FormBorderSytle.None. Trên Windows CE thì sự định vị của cửa sổ luôn luôn bằng nhau về kích thước cho thuộc tính Location, trừ khi ứng dụng được đặt trong trạng thái minimize hoặc maximize. 2.6 Điều khiển Button Lớp System.Windows.Forms.Button là lớp thực hiện .NET của một điều khiển nút bấm. Khi người sử dụng kích vào nút bấm bằng một cái bút, thì một sự kiện click được xuất hiện. Bạn có thể điều khiển sự kiện này bởi một phương thức (một lớp) delegate System.EventHandler. Code dưới đây thực thi sự kiện EventHandler được hiển thị ở ngay thời gian hiện tại. C# Private void button_Click(object sender, System.EventArgs e) { MessageBox.Show(DateTime.Now.ToShortTimeString(), "The Current Time Is", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);} Hình 2.5 hiển thị chương trình đang chạy trên bộ mô phỏng Pocket PC. Cái nút bấm có nhãn là What is the Time?, và khi nó được kích thì nó sẽ hiển thị thời gian hiện tại trong một hộp thoại. Hình 2.5: Chạy ứng dụng GiveEmTime trên bộ mô phỏng Pocket PC 2002 Bảng 2.4: KeyCodes tự phát sinh bởi Directional Pad trên một thiết bị Pocket PC KeyCode VALUE ASSOCIATED HARDWARE BUTTON Keys.Up The top of the pad was pressed. Keys.Down The bottom of the pad was pressed. Keys.Left The left side of the pad was pressed. Keys.Right The right side of the pad was pressed. Keys.Return The center of the pad was pressed. 2.7 Sử dụng điều khiển TextBox Điều khiển TextBox được sử dụng để nhận dữ liệu từ người dùng nhập vào. Điều khiển TexBox hỗ trợ các thuộc tính BackColor và ForeColor, nó không giống như đa số các điều khiển khác trong .NET Compact Framework. sự kiện click không được hỗ trợ, nhưng những sự kiện KeyPress, KeyUp, và KeyDown lại được hỗ trợ. Thuộc tính PasswordChar được hỗ trợ. Và khi ta thiết lập thuộc tính này thì các kí tự nhập vào sẽ được chuyển thành các dâu sao (*) để che dấu các kí tự đó. 2.8 Sử dụng điều khiển Label. Điều khiển Label cho phép bạn trình bày đoạn văn bản đến người sử dụng. Đây là một điều khiển đơn giản mà nó không cấn giải thích nhiều. Thuộc tính Text của điều khiển xác định điều mà văn bản sẽ hiển thị rõ ràng tới người sử dụng. Hiển thị đoạn văn bản có thể có sự liên kết khác nhau dựa trên thuộc tính TextAlign. Có thể xảy ra những giá trị canh lề như: TopLeft, TopCenter, và TopRight. Sự kiện TextChanged được thực thi khi đoạn văn bản trong một điều khiển Label thay đổi. HANDLING THE POCKET PC HARDWARE BUTTONS Pocket PC có một pad (miếng đệm) đinh hướng mà có thể sử dụng để tương tác với những ứng dụng Pocket PC. Nó có thể thực hiện bắt những sự kiện mà pad này sinh ra. Khi nào pad được nhấn, thì một sự kiện KeyDown được phát sinh phù hợp với đối tượng form. Bộ xử lý sự kiện nhận được một đối tượng KeyEventArgs. Đối tương KeyEventArgs đưa ra thuộc tính KeyCode. Bạn có thể kiểm tra giá trị của thuộc tính KeyCode để xác định rõ điều khiển nào trên pad được nhấn. Bảng 2.4 là bảng liệt kê những thành phần key mà có thể là gán cho thuộc tính KeyCode và nút kết hợp với chúng. 2.9 Điều khiển RadioButton. Những điều khiển nút Radio phổ biến hiện nay đưa cho những người sử dụng một mảng những sự lựa chọn, và người sử dụng chỉ được chọn một trong các lựa chọn đó. Khi một nút rađiô trong một nhóm được lựa chọn, thì các nút còn lại sẽ tự động xoá. Những nút Rađiô được đặt vào cùng một nhóm giống nhau, nếu chúng giống nhau. Một ứng dụng có thể có nhiều nhóm nút rađiô. Lớp RadioButton đưa ra hai sự kiện mà được thực thi khi trạng thái kiểm tra của một RadioButton thay đổi: click và CheckedChanged. Sự kiện click được đưa ra khi một người sử dụng kích vào nút rađiô bằng bút nhọn. Bạn có thể xử lý sự kiện click này giống như bạn xử lý sự kiện click cho lớp Botton. Sự kiện CheckedChanged được đưa ra khi ta thay đổi trạng thái kiểm tra của RadioButton Sự kiện click sẽ không được đưa ra nếu thuộc tính Checked của RadioButton được thay đổi theo chương trình. Ứng dụng Arnie.exe giải thích việc sử dụng một nhóm điều khiển RadioButton như thế nào. (Bạn có thể tìm thấy mã cho ứng dụng này trong chương trình mẫu Arnie của quyển sách này.) Hình 2.6 hiển thị ứng dụng đang chạy trong bộ mô phỏng Pocket PC. Hình 2.6: Chạy ứng dụng Arnie trên bộ mô phỏng Pocket PC 2002. Khi một phim (movie) được lựa chọn, ứng dụng sẽ bắt sự kiện CheckedChanged của RadioButton, và một hộp thoại được hiển thị nếu đúng RadioButton được kiểm tra. Mã sau đây trình bày việc xử lý sự kiện CheckedChanged như thế nào cho một câu trả lời sai. C# private void radioButton2_CheckedChanged(object sender, System.EventArgs e) { if(this.radioButton2.Checked) MessageBox.Show ("Wrong, The Terminator (1984) O.J Simpson almost got the role...", "Wrong!"); } 2.10 Sử dụng điều khiển CheckBox Điều khiển CheckBox tương tự như điều khiển RadioButton, chúng cũng có một tập danh sách để lựa chọn. Nhưng nó khác với điều khiển RadioButton là nếu trong điều khiển RadioButton, người sử dụng chỉ được chọn một lựa chọn trong danh sách các lựa chọn, còn với điều khiển CheckBox thì người sử dụng có thể được chọn nhiều lựa chọn khác nhau cùng một lúc. Điều khiển CheckBox thông thường là một GUI có giá trị kiểu Boolean hoặc là một biểu thức. Điều khiển CheckBox cung cấp thuộc tính CheckState, mà nó xác định rằng liệu CheckBox có được kiểm tra hay không. Thuộc tính CheckState thật sự là một bảng liệt kê, bảng liệt kê CheckState . Những hàm thành phần của nó là Unchecked, Checked, và Indeterminate. Unchecked và Check thì ta không phải giải thích gì thêm. Trạng thái Indeterminate có thể chỉ được sử dụng khi thuộc tính ThreeState của điều khiển CheckBox là true. Khi CheckState là Indeterminate và thuộc tính ThreeState là true, thì điều khiển sẽ được đánh dấu là màu xám nhưng nó vẫn được kiểm tra. Điều đó báo hiệu rằng trạng thái đó đã được kiểm tra. Điều khiển sẽ không phản ứng lại với điều kiện là thuộc tính AutoCheck là false. Khi thuộc tính AutoCheck thiết đặt là true thì một sự kiện click với bút bấm sẽ cho phép điều khiển. Ứng dụng Apples.exe là một ví dụ đơn giản khác mà nó thử xác định xem người sử dụng thích kiểu apples gì. Hình 2.7 hiển thị ứng dụng đang chạy trong bộ mô phỏng Pocket PC. Mã đầy đủ cho ứng dụng này có thể được tìm thấy trong mã nguồn của quyển sách này. Hình 2.7: Một ứng dụng của các điều khiển CheckBox chạy trên bộ mô phỏng Pocket PC 2002. 2.11. Sử dụng điều khiển ComboBox. Điều khiển ComboBox là điều khiển lý tưởng để đưa ra một danh sách của những lựa chọn trong một số lượng được hạn chế của không gian màn hình. ComboBox xuất hiện như một điều khiển TextBox với một mũi tên bên phải. Một danh sách của những tùy chọn được thả xuống ở dưới điều khiển khi người sử dụng kích vào mũi tên. Khi người sử dụng lựa chọn một tùy chọn họăc kích vào mũi tên lần nữa, thì danh sách của những tùy chọn sẽ cuộn lên. Thêm những mục chọn cho điều khiển ComboBox có thể được làm ở cả lúc thiết kế và cả ở thời điểm chạy. Để thêm những mục chọn cho ComboBox trong lúc thiết kế, đơn giản ta chọn ComboBox trong Form Designer. Sau đó kích vào dấu ba chấm ở bên cạnh thuộc tính Items trong cửa sổ Properties. Nó sẽ đưa ra cửa sổ String Collection Editor ( Chúng ta sẽ nhìn thấy trong hình 2.8). Trong String Collection Editor, ta sẽ nhập vào danh sách mục chọn để nó xuất hiện trong ComboBox. Mỗi mục chọn phải xuất hiện trên một hàng riêng biệt. Hình 2.8:Cửa sổ String Collection Editor. Mục chọn cũng có thể được thêm vào điều khiển ComboBox ở thời điểm. Việc này có thể được hoàn thành trong hai cách khác nhau. Đầu tiên, ta gọi phương thức Add trên thuộc tính tập hợp Items của điều khiển ComboBox. Những mục chọn có thể được loại bỏ thông qua phương thức Remove trên tập Items, hay tất cả các mục chọn có thể được loại bỏ bằng cách gọi phương thức Clear. Đoạn mã sau đây thực hiện việc thêm ba chuỗi cho một điều khiển ComboBox có tên là comboBox1: C# comboBox1.Items.Add("Hi"); comboBox1.Items.Add("Howdy"); comboBox1.Items.Add("Wuz Up"); Bạn cũng có thể thêm những mục chọn cho một ComboBox ở thời điểm chạy bằng cách liên kết điều khiển cho một đối tượng collection. Việc này được thực hiện bằng cách đặt DataSource cho đối tượng collection. Khi ComboBox cố gắng để thêm những mục chọn vào danh sách thả xuống, nó sẽ gọi đến phương thức ToString trên mỗi mục chọn trong DataSource và thêm các chuỗi vào danh sách thả xuống. Chuỗi có thể tùy biến bởi sự thiết đặt thuộc tính DisplayName của điều khiển ComboBox Đoạn mã sau giải thích việc liên kết một ComboBox với một danh sách của những đối tượng tuỳ biến như thế nào. Lớp Customer là một lớp tuỳ biến mà nó nắm giữ tên của tuỳ biến đó. Khi ComboBox được giới hạn trong phương thức LoadCustomer, thì thuộc tính FullName được đặt như DisplayName. Đoạn mã C# class Customer { string m_First; string m_Middle; string m_Last; public Customer(string first, string middle, string last) { m_First = (first == null) ? string.Empty : first; m_Middle = (middle == null) ? string.Empty : middle; m_Last = (last == null) ? string.Empty : last; } public string FirstName { get { return m_First; } } public string MiddleName { get { return m_Middle; } } public string LastName { get { return m_Last; } } static string FullNameWithInitial = "{0} {1}. {2}"; static string FullNameNoInitial = "{0} {1}"; public string FullName { get { return (m_Middle.Length > 0) ? string.Format(FullNameWithInitial, m_First, m_Middle[0], m_Last) : string.Format(FullNameNoInitial, m_First, m_Last); } } } private void LoadCustomers() { if(customers != null) return; customers = new Customer[6]; customers[0] = new Customer("Ronnie", "Donnell", "Yates"); customers[1] = new Customer("Moya", "Alicia", "Hines"); customers[2] = new Customer("Veronica", "Christine", "Yates"); customers[3] = new Customer("Diane", "", "Taylor"); customers[4] = new Customer("Kindell", "Elisha", "Yates"); customers[5] = new Customer("Zion", "Donnell", "Yates"); this.comboBox1.DataSource = customers; this.comboBox1.DisplayMember = "FullName"; } Có hai cách vẫn được sử dụng mà mục chọn hiện thời được lựa chọn trong ComboBox. Đầu tiên, thuộc tính mục chọn SelectedIndex trả lại chỉ số của mục chọn hiện thời được lựa chọn. Chỉ số này có thể được dùng để truy cập mục chọn được lựa chọn từ thuộc tính Items của điều khiển ComboBox. Mã sau đây minh họa thuộc tính SelectIndex : C# string selItem = comboBox1.Items[comboBox1.SelectedIndex].ToString(); Điều khiển ComboBox cũng cung cấp thuộc tính electedItem mà trả lại một tham chiếu đến mục chọn hiện thời được lựa chọn. Mã sau đây trình bày việc sự sử dụng thuộc tính SelectedItem như thế nào: C# string selItem = comboBox1.SelectedItem.ToString(); 2.12 Sử dụng điều khiển ListBox ComboBox là một điều khiển lý tưởng cho những ứng dụng trong những môi trường có không gian giới hạn, nhưng với ListBox có thể được sử dụng nếu không gian màn hình hiển thị vài tùy chọn cùng một lúc cho người sử dụng. ComboBox và ListBox hầu như dùng chung tập hợp những thuộc tính và những phương thức giống như nhau. Nó bao gồm tập thuộc tính Items và các phương thức Add, Remove, và Clear trên thuộc tính Items. Chẳng hạn, mã sau đây thêm những chuỗi kí tự cho một ListBox điều khiển khi thực hiện. Mã sau đây gần giống với mã được dùng để thêm chuỗi kí tự cho một điều khiển ComboBox. C# listBox1.Items.Add("Hi"); listBox1.Items.Add("Howdy"); listBox1.Items.Add("Wuz Up"); Ngoài ra bạn cũng có thể thêm những mục chọn cho điều khiển ListBox ở tại thời điểm thực hiện bằng cách ràng buộc ListBox cho một tập hợp. Quá trình của sự ràng buộc một điều khiển ListBox giông hệt sự ràng buộc của một điều khiển ComboBox. Đầu tiên, đặt cho DataSource một tập hợp. Tiếp theo đặt DisplayMember cho thuộc tính mục chọn nguồn mà sẽ được sử dụng như chuỗi hiển thị. C# private void LoadCustomers() { if(customers != null) return; customers = new Customer[6]; customers[0] = new Customer("Ronnie", "Donnell", "Yates"); customers[1] = new Customer("Moya", "Alicia", "Hines"); customers[2] = new Customer("Veronica", "Christine", "Yates"); customers[3] = new Customer("Diane", "", "Taylor"); customers[4] = new Customer("Kindell", "Elisha", "Yates"); customers[5] = new Customer("Zion", "Donnell", "Yates"); this.listBox1.DataSource = customers; this.listBox1.DisplayMember = "FullName"; } 2.13 Các điều khiển khác 2.13.1 Sử dụng điều khiển NumericUpDown Điều khiển NumericUpDown là một cách đơn giản để cho người sử dụng lựa chọn một giá trị mà nó rơi giữa một số nhỏ nhât và một số lớn nhất. Điều khiển có thể chỉ chấp nhận những số nguyên, và những giá trị thập phân sẽ được làm tròn. Trên Pocket PC, giá trị cực đại không thể lớn hơn 16-bit số nguyên. Điều khiển NumericUpDown được kiểm soát bởi bốn thuộc tính số nguyên Minimum, Maximum, Value, và Increment. Những thuộc tính Minimum và Maximum xác định giá trị nhỏ nhất và giá trị lớn nhất của điều khiển. Thuộc tính Value là giá trị hiện tại của điều khiển. Thuộc tính Increment xác định số lượng qua giá trị hiện tại được tăng lên hay giảm xuống khi người sử dụng kích vào nút hướng lên trên hay nút hướng xuống. Giá trị hiện tại luôn luôn là tăng hay giảm qua giá trị Increment, trừ khi giá trị kết quả vượt ra khỏi phạm vi được định nghĩa bởi giá trị Minimum và Maximum Ngoài ra, người sử dụng cũng có thể thay đổi thuộc tính Value bằng cách gõ vào một giá trị mới trong điều khiển. Nếu giá trị mà người sử dụng nhập vào nằm giữa các giá trị Minimum và Maximum, thì cả hai thuộc tính Value và Text sẽ được thay đổi để giá trị mới được nhập vào. Nếu giá trị mới vượt ra ngoài tập giới hạn, thì thuộc tính Text nhận giá trị được nhập vào, trong khi thuộc tính Value sẽ nhận giá trị của thuộc tính Maximum. Để những người sử dụng nhập đúng dữ liệu vào trong điều khiển, thì ta thiết đặt thuộc tính ReadOnly là true. Khi một người sử dụng thay đổi giá trị của điều khiển NumericUpDown , một sự kiện ValueChanged được thực hiện. Sự kiện ValueChanged chỉ được thực hiện khi giá trị được thay đổi thông qua mã hay qua những mũi tên lên và xuống. Sự kiện đó sẽ không được thực hiện khi một người sử dụng nhập vào trong điều khiển. Đoạn code sau trình bày việc sử dụng điều khiển NumericUpDown như thế nào để xử lý sự kiện ValueChanged Đoạn code C# using System; using System.Drawing; using System.Collections; using System.Windows.Forms; using System.Data; namespace NumericUpDown { public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.NumericUpDown numericUpDown1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.MainMenu mainMenu1; public Form1() { InitializeComponent(); } protected override void Dispose( bool disposing ) { base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.mainMenu1 = new System.Windows.Forms.MainMenu(); this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); // // numericUpDown1 // this.numericUpDown1.Location = new System.Drawing.Point(8, 56); this.numericUpDown1.Maximum = new System.Decimal(new int[] {2003, 0, 0, 0}); this.numericUpDown1.Minimum = new System.Decimal(new int[] {1900, 0, 0, 0}); this.numericUpDown1.Value = new System.Decimal(new int[] {190012, 0, 0, 131072}); this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged); // // label1 // this.label1.Location = new System.Drawing.Point(8, 24); this.label1.Size = new System.Drawing.Size(184, 16); this.label1.Text = "In what year were you born?"; this. label1.ParentChanged += new System.EventHandler(this.label1_ParentChanged); // // label2 // this.label2.Location = new System.Drawing.Point(8, 120); this.label2.Size = new System.Drawing.Size(224, 24); // // Form1 // this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.numericUpDown1); this.Menu = this.mainMenu1; this.Text = "Form1"; } #endregion static void Main() { Application.Run(new Form1()); } static string msg = "You are ~{0} years young."; private void numericUpDown1_ValueChanged(object sender, System.EventArgs e) { int yearsOld = System.DateTime.Now.Year - (int)this.numericUpDown1.Value; this.label2.Text = String.Format(msg, yearsOld); } } Hình 2.9: Hiển thị ứng dụng đang chạy trên bộ mô phỏng Pocket PC 2002. Hình 2.9: Một ứng dụng có sử dụng điều khiển NumericUpDown đang chạy trên bộ mô phỏng Pocket PC 2002. 2.13.2 Sử dụng điều khiển DomainUpDown Điều khiển DomainUpDown tương tự như điều khiển NumericUpDown , chỉ khác nhau ở một điểm là DomainUpDown có thể hiển thị một danh sách của những chuỗi kí tự, còn điều khiển NumericUpDown chỉ có thể hiển thị một danh sách những số nguyên. Điều khiển DomainUpDown hiển thị một danh sách của những tùy chọn một cách rất hiệu quả vì nó có thể hiển thị chỉ một tùy chọn tại một thời điểm cho người sử dụng. Điều khiển xuất hiện như một textbox với một cặp mũi tên lên và xuống ở bên cạnh phải của điều khiển. Người sử dụng có thể di chuyển thông qua danh sách trong ba cách khác nhau: Bạn kích vào mũi tên có chiều lên thì nó sẽ di chuyển danh sách tuỳ chọn lên trên và ngược lại. Nếu thuộc tính ReadOnly được thiết đặt là false thì người sử dụng có thể nhập tên của mục chọn trong danh sách. Trong đa số những thiết bị Pocket PC đều có một nút mà có thể được dùng để định hướng điều khiển DomainUpDown. Việc nhấn nút này lên và xuống sẽ tương ứng với việc di chuyển lên và xuống những mục chọn trong danh sách. Nếu đặt thuộc tính ReadOnly là false, thì người sử dụng có thể nhập đoạn văn bản vào trong điều khiển mà đoạn văn bản đó có thể không phù hợp với một mục chọn trong danh sách. Thuộc tính Text sẽ trả lại đoạn văn bản hiện thời trong điều khiển. Điều này có nghĩa là bạn có thể cần kiểm tra việc nhập vào nếu ReadOnly đặt là false. Bởi vì việc kiểm tra đầu vào không được thực hiện qua điều khiển DomainUpDown, nên đoạn văn bản nhập vào trong điều khiển sẽ không lựa chọn một mục chọn tương ứng. Việc thiết đặt thuộc tính ReadOnly là true thì sẽ giới hạn người sử dụng lựa chọn những mục chọn duy nhất trong danh sách, như vậy sẽ loại trừ việc kiểm tra đầu vào. Điều khiển DomainUpDown đưa ra thuộc tính Items, nó miêu tả danh sách của các mục chọn trong điều khiển. Bạn có thể thêm những mục chọn vào danh sách bằng cách sử dụng phương thức Add đặt vào thuộc tính Items. Mã sau đây sẽ giải thích việc thêm ba mục chọn cho một điều khiển DomainUpDown như thế nào: C# DomainUpDown dud = new DomainUpDown(); dud.Items("TX"); dud.Items("LA"); dud.Items("WA"); Ngoài ra, bạn cũng có thể thêm những mục chọn cho điều khiển DomainUpDown ở lúc thiết kế. Đầu tiên, ta lựa chọn điều khiển trong Form Designer. Tiếp theo, trong cửa sổ Properties, kích vào nút ba chấm bên cạnh thuộc tính Items. Việc làm này đưa ra một hộp thoại String Collection Editor ( Như ta thấy trong hình 2.9). Điều khiển DomainUpDown trình bày hai thuộc tính mà cho phép bạn xác định đoạn văn bản hiện thời trong điều khiển: Thuộc tính Text là chuỗi kí tự mà hiện thời đang được hiển thị trong điều khiển. Giá trị trả về không nhất thiết là một mục chọn trong danh sách. Thuộc tính SelectedIndex là chỉ số của mục chọn trong danh sách mà hiện thời đang hiển thị cho người sử dụng. Bạn có thể sử dụng thuộc tính này chung với thuộc tính Items để được giá trị chuỗi kí tự của mục chọn. Khi thuộc tính Text được thay đổi, một sự kiện TextChanged được thực thi, và khi thuộc tính SelectedIndex được thay đổi thì một sự kiện SelectedIndexChanged được thực thi. Sự kiện SelectedIndexChanged được thực thi chỉ khi chỉ số được thay đổi qua code hoặc qua việc kích vào các mũi tên lên và xuống. Sự kiện sẽ không được thực thi khi người sử dụng nhập vào điều khiển. code dưới đây trình bày việc xử lý cả hai sự kiện: C# private void domainUpDown1_SelectedItemChanged(object sender, System.EventArgs e) { int selNdx = this.domainUpDown1.SelectedIndex; string selStr = this.domainUpDown1.Items[selNdx].ToString(); MessageBox.Show("You selected " + selStr); } private void domainUpDown1_TextChanged(object sender, System.EventArgs e) { string selStr = this.domainUpDown1.Text; MessageBox.Show("You selected " + selStr); } 2.13.3 Điều khiển ProgressBar Điều khiển ProgressBar đưa ra cho những người sử dụng một biểu diễn đồ hoạ của một thao tác đang tiến triển như thế nào. Nó có ích khi ứng dụng của bạn cần thực hiện một thao tác tốn nhiều thời gian và bạn không muốn người sử dụng nghĩ rằng ứng dụng của bạn là không thực hiện hoặc nó đang rơi vào trạng thái lặp vô tân. Điều khiển ProgressBar được kiểm soát bởi ba thuộc tính Int32: Minimum, Maximum, và Value. Những giá trị Minimum và Maximum xác định giá trị lớn nhất và giá trị nhỏ nhất của điều khiển ProgressBar. Thuộc tính Value xác định giá trị của điều khiển ProgressBar. Điều khiển ProgressBar sẽ được điền các giá trị từ bên trái sang bên phải khi thuộc tính Value sẽ tăng dần lên từ giá trị Minimum đến giá trị Maximum. Điều khiển ProgressBar rỗng khi thuộc tính Value bằng với thuộc tính Minimum. Và mỗi một lần thuộc tính Value bằng giá trị Maximum thì điều khiển ProgressBar sẽ đạt tới giá trị lớn nhất. Ngay sau khi thuộc tính Value được thay đổi thì điều khiển ProgressBar sẽ nhận một giá trịn mới. Hình 2.10 và hình 2.11 hiển thị một chương trình game BombSquad.exe đang chạy trong bộ mô phỏng Pocket PC 2002. Game BombSquad là một trò chơi đơn giản, nó đặt cho bạn một lượng thời gian để khuếch tán một quả bom nguy hiểm bằng cách kích vào nút Diffuse trước khi điều khiển ProgressBar được làm đầy. Vị trí của nút Diffuse liên tục thay đổi trong khi trò chơi đang được chơi. Hình 2.10 hiển thị kết quả thành công của việc khuếch tán, và hình 2.11 hiển thị kết quả không thành công của viêc khuếch tán bom. Hình 2.10: Bạn chiến thắng trò chơi BombSquad bằng cách khuếch tán quả bom trước khi thanh progress bar đầy Hình 2.11: Bạn thua cuộc trong trò chơi BombSquad bằng cách khuếch tán quả bom trước khi thanh progress bar đầy 2.13.4. Sử dụng điều khiển StatusBar Thanh trạng thái là một vùng nhỏ thường nằm ở cuối của một form, nó trình bày thông tin trạng thái ở ngay thời điển đang làm việc cho người sử dụng. Thanh trạng thái này chỉ có thể hiển thị thông tin đoạn văn bản. Tác dung chung của thanh trạng thái là cung cấp cho người dùng một câu đơn giản mà nó mô tả trạng thái của ứng dụng hay nói cách khác rằng những thao tác gì mà người sử dụng đang thực hiện ngay thời điểm đó, thì nó sẽ hiển thị trạng thái hiện thời của ứng dụng. Nó cũng có thể thay thế một điều khiển ProgressBar để trình bày tình trạng của những thao tác cần nhiều thời gian. Để cập nhật một điều khiển StatusBar, đơn giản ta chỉ việc thay đổi giá trị của thuộc tính Text. Khi văn bản được thay đổi, thì điều khiển tự động được thay đổi để hiển thị văn bản mới. Hình 2.12 trình bày một ứng dụng mà nó bắt đầu và kết thúc một điều khiển Timer. Hình 2.12: Một ứng dụng đơn giản có sử dụng điều khiển StatusBar đang chạy trên bộ mô phỏng Pocket PC 2002. 2.13.5. Sử dụng điều khiển TrackBar Điều khiển TrackBar là một điều khiển con trượt đặc biệt. Nó cho phép người sử dụng lựa chọn một giá trị số bằng cách thay đổi vị trí của con trượt. Điều khiển TrackBar được kiểm soát chủ yếu bởi ba thuộc tính : Minimum, Maximum, và Value. Ba thuộc tính này đã được giải thích ở trên. Điều khiển TrackBar đưa ra vài thuộc tính bổ sung mà nó kiểm soát sự xuất hiện và hoạt động của TrackBar. Thuộc tính Orientation xác định rằng liệu TrackBar được định hướng theo trục nằm ngang hay là trục thẳng đứng. Thuộc tính TickFrequency xác định khoảng cách giữa các dấu tích dọc theo con trượt. Theo mặc định thì TickFrequency được đặt là một đơn vị. Những thuộc tính SmallChange và LargeChange xác định những giá trị tăng dần. Thuộc tính SmallChange xác định thuộc tính Value được tăng thế nào khi người sử dụng nhấn một trong số những phím mũi tên trên thanh định hướng của Pocket PC. Thuộc tính LargeChange xác định thuộc tính Value được tăng thế nào khi người sử dụng kích lên điều khiển TrackBar trên mọi cạnh của con trượt. Khi giá trị của những điều khiển TrackBar được thay đổi, thì một sự kiện ValueChanged được thực hiện. Bạn có thể xử lý sự kiện này để cập nhật bất kỳ thuộc tính nào mà được liên kết với điều khiển TrackBar. Hình 2.13 cho thấy hai TrackBar giống hệt nhau nhưng một cái có hướng thẳng đứng và cái kia có phương nằm ngang. TrackBar nằm ngang điều khiển TrackBar thẳng đứng, có nghĩa là giá trị của điều khiển TrackBar thẳng đứng sẽ thay đổi để phù hợp giá trị của điều khiển TrackBar nằm ngang . Hình 2.13: Một ứng dụng hiển thị điều khiển TrackBar đang chạy trên bộ mô phỏng Pocket PC 2002. 2.13.6. Sử dụng điều khiển ToolBar Định hướng một thực đơn bằng một bút nhọn có thể trở nên không hấp dẫn, một cách đặc biệt nếu người sử dụng đang lựa chọn một mục trong thực đơn và làm lại giống như vậy một lần nữa. Điều khiển ToolBar có thể giảm bớt số lần kích mà một người sử dụng phải thực hiện để thực hiện những tùy chọn trong thực đơn. Vì điều khiển ToolBar gồm có những hình ảnh, nên việc thêm một ToolBar có thể làm cho ứng dụng của bạn sinh động hơn. Điều khiển ToolBar là một thanh công cụ sinh động, nó gồm có những hình ảnh, mỗi ảnh tương ứng với một nút bấm. Những nút này thông thường là những phím tắt phổ biến được sử dụng cho các chức năng của ứng dụng. Trên .NET Compact Framework thì điều khiển ToolBar không thể chứa một đoạn văn bản. Bạn phải sử dụng một điều khiển ImageList để ở điều khiển ToolBar. Điều khiển ToolBar có thể xuất hiện ở những vị trí khác nhau, phụ thuộc vào ứng dụng được xây dựng cho Pocket PC hay Windows CE. Nếu đó là một ứng dụng cho Windows CE, thì ToolBar sẽ xuất hiện dọc theo đỉnh của form ứng dụng và ở phía bên phải của bất kỳ tùy chọn thực đơn nào ( ta sẽ thấy trong hình 2.14). Với những ứng dụng trên Pocket PC thì ToolBar xuất hiện dọc theo đáy của form và ở bên phải của bất kỳ tùy chọn thực đơn nào ( ta sẽ thấy trong hình 2.15). Hình 2.14: Một ứng dụng sử dụng điều khiển ToolBar chạy trên bộ mô phỏng Windows CE .NET Hình 2.15:Một ứng dụng sử dụng điều khiển ToolBar chạy trên bộ mô phỏng Pocket PC 2002. Thêm một điều khiển ToolBar cho một ứng dụng Để thêm một điều khiển ToolBar cho một ứng dụng ta có thể sử dụng Form Designer trong Visual Studio .NET. Chúng ta sẽ lần lượt thực hiên theo các bước sau: Kéo một điều khiển ImageList vào trong form ứng dụng của bạn. Việc làm này sẽ tạo ra một biểu tượng ở phía cuối của Form Designer. Trong của sổ Properties của điều khiển ImageList kích vào nút ba chấm bên cạnh thuộc tính Images.Việc làm này sẽ đưa ra một của sổ Image Collection Editor (như ta thấy trong hình 2.16) Hình 2.16: Cửa sổ Image Collection Editor. Sử dụng cửa sổ Image Collection Editor để thêm những hình ảnh của ToolBar cho ImageList . Một điều quan trọng cần chú ý là những hình ảnh sẽ được thay đổi kích thước còn 16 X 16 pixels, đó là kích thước của tất cả các ảnh trên ToolBar. Những ảnh này cũng được đưa vào trong file tài nguyên (resource) cho ứng dụng. Kéo điều khiển ToolBar vào trong form ứng dụng. Đặt tên cho thuộc tính ImageList của điều khiển ToolBar đã được tạo ở bước 1. Đưa ra cửa sổ ToolBarButton Collection Editor (như ta thấy trong hình 2.17) bằng cách kích vào nút ba chấm bên cạnh thuộc tính Button của điều khiển ToolBar trong cửa sổ Properties. Hình 2.17: Cửa sổ ToolBarButton Collection Editor Thêm tất cả các nút bấm mà sẽ xuất hiện trên điều khiển ToolBar, thiết đặt thuộc tính ImageIndex cho mỗi nút bấm. ImageIndex có một chỉ số gốc là chữ số 0 mà tương ứng với chỉ số của một ảnh trong điều khiển ImageList. Nếu bạn không muốn nút bấm có kiểu dáng mặc định PushButton thì bạn thay đổi thuộc tính Style của nút bấm. Bảng 2.5 trình bày danh sách của tất cả các giá trị Style có thể xảy ra và một mô tả vắn tắt về nó. Bảng 2.5. Hàm thành phần của ToolBarButtonStyle và sự mô tả về chúng MEMBER NAME DESCRIPTION DropDownButton Khi nút bấm được kích, thì một menu hoặc cửa sổ khác được hiển thị. PushButton Bình thường, nút bấm có ba chiều (rộng, dài và sâu. mặc đinh) Separator Một space hoặc graphic giữa các nút bấm của toolbar ToggleButton Một nút mà khi ta kích vào nó thì nó bị ấn xuống. và nó sẽ giữ nguyên trạng thái đó cho đến khi nó được kích lại lần nữa. Xử lý sự kiện ButtonClick của ToolBar Khi một người sử dụng kích vào một nút trên điều khiển ToolBar, một sự kiện ButtonClick được thực hiện. Ta có thể xử lý sự kiện này để việc thực hiện hoạt động được gán cho nút được kích. Bộ xử lý sự kiện của sự kiện ButtonClick nhận được một đối tượng ToolBarButtonClickEventArgs . Thuộc tính ToolBarButtonClickEventArgs. Button là một tham chiếu cho nút ToolBar khi nó được kích. Ví dụ sau đây trình bày việc đưa ra điều khiển OpenFileDialog như thế nào khi nút ToolBar được kích. C# private void toolBar1_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e) { if(e.Button == this.toolBarButton1) { OpenFileDialog dlg = new OpenFileDialog(); if(dlg.ShowDialog() == DialogResult.OK) { this.lblOpenFile.Text = dlg.FileName; } } else if(e.Button == this.toolBarButton2) { SaveFileDialog dlg = new SaveFileDialog(); if(dlg.ShowDialog() == DialogResult.OK ) { this.lblSaveFile.Text = dlg.FileName; } } } Thêm các Menu bằng điều khiển MainMenu Sử dụng những Menu là một cách hiệu quả và dễ dàng để đưa ra những tùy chọn cho những người sử dụng. Những Menu được xử lý khác nhau, nó phụ thuộc vào ứng dụng của bạn đang chạy trên hệ điều hành Pocket PC hay hệ điều hành Windows CE. Theo mặc định một ứng dụng trên Pocket PC sẽ chứa một điều khiển MainMenu. Một ứng dụng trên Pocket PC hiển thị những menu ở đáy của màn hình ứng dụng. Những ứng dụng trên Windows CE không có mặc định cho menu, và những menu được hiển thị tại đỉnh của ứng dụng, nó giống như một chuẩn cho những ứng dụng trên desktop. Điều khiển MainMenu là một điều khiển mà nó chứa tất cả những điều khiển trong ứng dụng. Những menu với những mục chọn mức dưới có thể được tạo ra bằng cách thêm nhiều mục chọn cho MenuItem ở mức đỉnh. Bạn có thể thêm những menu cho ứng dụng của bạn ở thời điểm thiết kế hoặc tại thời điểm chạy thông qua trình thiết kế menu. Code đưới đây trình bày việc làm thế nào để thêm một mục chọn menu với hai mục chọn trình đơn phụ cho điều khiển MainMenu được đặt tên là MainMenu1. Ngoài ra, code cũng giải thích việc làm thế nào để thêm một dụng cụ chia tách cho một menu. Việc này được làm bằng cách tạo một đối tượng MenuItem mới và đặt cho đoạn văn bản của nó một chuổi kí tự có chứa kí tự là dấu nối đơn “-”. C# MenuItem fileMenu = new MenuItem(); MenuItem newItem = new MenuItem(); MenuItem sepItem = new MenuItem(); MenuItem exitItem = new MenuItem(); fileMenu.Text = "File"; newItem.Text = "New"; sepItem.Text = "-"; exitItem.Text = "Exit"; fileMenu.MenuItems.Add(newItem); fileMenu.MenuItems.Add(sepItem); fileMenu.MenuItems.Add(exitItem); mainMenu1.MenuItems.Add(fileMenu); Hình 2.18: Trình bày một menu đang được hiển thị trên bộ mô phỏng Pocket PC 2002. Hình 2.18: Một ứng dụng đơn giản có sử dụng điều khiển MainMenu đang được chạy trên bộ mô phỏng Pocket PC 2002. Khi người sử dụng chọn một mục chọn trong menu thì một sự kiện Click được thực thi. Bạn xử lý sự kiện này tương tự như việc xử lý sự kiện Click của điều khiển Button. 2.13.7 Sử dụng điều khiển ContextMenu trong một ứng dụng. Điều khiển ContextMenu tương tự như điều khiển MainMenu nhưng có loại trừ những menu ngữ cảnh được kết hợp với những điều khiển khác, trong khi MainMenu được kết hợp với form của ứng dụng. Ngoài ra, những ContextMenu cũng được biết đến như những menu xoè ra mà xuất hiện khi bạn nhấn nhẹ và giữ một điều khiển trên Pocket PC hay kích phải chuột lên một điều khiển trên Windows CE. Để thêm một ContextMenu cho một ứng dụng, thì ta kéo điều khiển đến từ hộp ToolBox lên trên ứng dụng. Điều khiển ContextMenu mới sẽ xuất hiện trong panel ở đáy của Form Designer. Khi ContextMenu được lựa chọn, thì Form Designer đặt điều khiển ở chỗ thích hợp giống như điều khiển MainMenu. Ở tại thời điểm thực thi, ContextMenu sẽ xuất hiện ở trên điều khiển tương ứng của nó. Để thêm MenuItem cho ContextMenu, bạn kích vào ContextMenu trên Form hay kích vào liên kết Edit menu trong cửa sổ Properties. Link Edit Menu chỉ hiện rõ khi ContextMenu được chọn. Ngoài ra, bạn cũng có thể tạo những điều khiển ContextMenu ở thời điểm thực thi. Đầu tiện một điều khiển ContextMenu phải được khởi tạo. Tiếp theo ta thêm những đối tượng MenuItem cho nó, và sau đó đặt thuộc tính ContextMenu của một điều khiển cho ContextMenu thể hiện. Mã sau đây trình bày việc làm thế nào để thêm một ContextMenu ở thời điểm thực thi: C# ContextMenu cMenu = new ContextMenu(); MenuItem menuItem1 = new MenuItem(); MenuItem menuItem2 = new MenuItem(); menuItem1.Text = "Default Item 1"; menuItem2.Text = "Default Item 2"; // Add menuItem2 as a child of menuItem1 menuItem1.MenuItems.Add(this.menuItem2); // Add menuItem1 to the context menu cMenu.MenuItems.Add(this.menuItem1); // Add the context menu to a label control label1.ContextMenu = cMenu; Khi một ContextMenu được gọi đến thì một sự kiện Popup được thực thi. Sự kiện này có thể được xử lý với tùy biến ContextMenu trước khi nó được hiển thị đến người sử dụng. Khi một MenuItem được lựa chọn từ ContextMenu, thì một sự kiện Click được thực thi cho MenuItem. Hình 2.19 cho thấy một ứng dụng có sử dụng một điều khiển ContextMenu đang được chạy. Những MenuItem trên điều khiển được định hình khi nó được kích hoạt. những điều khiển CheckBox xác định những MenuItem nào sẽ được hiển thị. Menu Default Item1 luôn luôn được hiển thị. Hình 2.19: Một ứng dụng đơn giản có sử dụng điều khiển ContextMenu đang được chạy trên bộ mô phỏng Pocket PC 2002. 2.13.8 Sử dụng điều khiển Timer Đều khiển Timer cho phép bạn thực hiện mã xử lý sự kiện lặp đi lặp lại nhiều lần trong những khoảng thời gian xác định. Nếu code của bạn cần chạy một Thead (chuỗi) ngoài thread của Windows, thì bạn phải sử dụng không gian tên System.Threading. Điều khiển Timer được thực thi bởi một sự kiện Tick. Một sự kiện Tick chỉ xuất hiện khi thuộc tính Enabled của Timer được đặt là true. Bạn có thể dừng một điều khiển Timer bằng cách đặt thuộc tính Enabled là false. Thuộc tính Interval của điều khiển Timer xác định số lượng của một phần nghìn giây giữa những sự kiện Tick. Trong mục “Chương trình điều khiển ProgressBar”, chúng ta đã nói đến chương trình game BombSquad.exe. Đối tượng của trò chơi là sẽ kích vào nút Diffuse trước khi điều khiển ProgressBar được làm đầy. Điều chú ý là vị trí của nút Diffuse liên tục thay đổi, trong khi giá trị của ProgressBar đang tăng lên. Ứng dụng này sử dụng hai thiết bị bấm giờ. Một điều khiển Timer được xác định như thế nào để giá trị của ProgressBar được cập nhật. Và một điều khiển Timer khác được xử lý sự di chuyển của nút Diffuse xung quanh form. Đoạn code trình bày hai Timer được xử lý như thế nào. Đoạn mã: C# private void timerButtonMove_Tick(object sender, System.EventArgs e) { if(!gameOver) { this.button1.Location = new Point(rand.Next(0, 168), rand.Next(0, 216)); }else { EndGame(); } } private void timerProgressBar_Tick(object sender, System.EventArgs e) { if( counter < 60 ) { if( gameOver ) return; if(this.progressBar1.Value < this.progressBar1.Maximum) this.progressBar1.Value += 1; ++counter; } else { if( !gameOver ) { EndGame(); MessageBox.Show("Boom!", "Loser"); } } } private void EndGame() { this.timerButtonMove.Enabled = false; this.timerProgressBar.Enabled = false; counter = 0; this.gameOver = true; this.button2.Enabled = true; } 2.13.9 Sử dụng các điều khiển OpenFileDialog và SaveFileDialog Một nhiệm vụ chung cho mỗi ứng dụng là mở hay lưu giữ một file mà nó là kết quả của dữ liệu của ứng dụng. Trong những ứng dụng của Windows thì những hộp thoại Open và Save file cung cấp một cách dễ dàng cho người sử dụng để định vị một file. .NET Compact Framework cung cấp những điều khiển OpenFileDialog và SaveFileDialog để tương tác với những hộp thoại này.Trên Windows CE và Pocket PC, những điều khiển này chỉ cho phép bạn xác định vị trí của thư mục My Documents và một thư mục bên dưới. Có vài thuộc tính đáng quan tâm mà bạn có thể xem xét sự thiết đặt trước khi hiển thị một trong số những hộp thoại file cho người sử dụng. Đầu tiên là đặt thuộc tính Filter, nó xác định những kiểu file và những mở rộng của file được liệt kê trong mọi hộp thoại file. Chẳng hạn, xâu kí tự sau đây chỉ cho phép những file có đuôi mở rộng là .dll hay.exe được liệt kê trong hộp thoại: "Dynamically Linked Library|*.dll|Executable|*.exe" Mỗi file filter sẽ được thêm vào menu thả xuống Files Type trong hộp thoại Open hoặc Save. Bạn có thể thay đổi file filter hiện thời được lựa chọn bằng cách đặt thuộc tính FilterIndex . Giá trị mặc định của thuộc tính này là 1. Để hiển thị một hộp thoại file Open hay Save , ta gọi phương thức ShowDialog trên cả hai điều khiển OpenFileDialog hay SaveFileDialog. Khi gọi phương thức này thì hộp thoại Open hay Save sẽ hiển thị và vì vậy nó sẽ làm tạm ngừng quá trình làm việc cho đến khi người sử dụng kích vào nút OK hoặc nút Cancel. ShowDialog trả ra một giá trị liệt kê DialogResult. DialogResult có vài hàm thành phần, nhưng phương thức ShowDialog sẽ chỉ trả về DialogResult.OK hay DialogResult.Cancel. Nếu DialogResult.OK được trả lại, thì người sử dụng đang kích vào nút Ok, và bạn có thể kiểm tra thuộc tính Filename để khôi phục đường dẫn đầy đủ của file của người sử dụng được lựa chọn. Nếu DialogResult.Cancel được trả về thì người sử dụng được kích vào nút Cancel để loại bỏ hộp thoại. Những điều khiển có sự khác nhau về sự hiển thị, nó phụ thuộc vào hệ điều hành mà chúng đang chạy. Trên Pocket PC, những hộp thoại sẽ xuất hiện chiếm toàn màn hình. Trên Windows CE, một hộp thoại sẽ xuất hiện như một cửa sổ hội thoại mở ra ở trên ứng dụng. Mã sau đây giải thích việc làm như thế nào để hiển thị một điều khiển OpenFileDialog mà có danh sách các file với đuôi mở rộng là .dll hay .exe. Nếu một file được lựa chọn, thì một hộp thoại sẽ xuất hiện với tên file đầy đủ. C# OpenFileDialog ofDlg = new OpenFileDialog(); ofDlg.Filter = "DLL|*.dll|Executable|*.exe"; ofDlg.IntialDirectory = "\\My Documents"; if(DialogResult.OK == ofDlg.ShowDialog()) { MessageBox.Show("You Selected " + ofDlg.FileName); } else { MessageBox.Show("Go ahead, select a file!"); } 2.13.10. Sử dụng điều khiển Panel. Điều khiển Panel là một điều khiển mà nó chứa những điều khiển khác. Bạn có thể thêm những điều khiển cho Panel vào thời gian thiết kế và thời gian thực thi. Những panel thông thường được dùng để nhóm những điều khiển có liên quan lại với nhau. Chẳng hạn, trong .NET Compact Framework không hỗ trợ điều khiển GroupBox, cái mà có thể được dùng để nhóm những điều khiển RadioButton lại với nhau. Thay vào đó, bạn có thể thêm những điều khiển RadioButton cho một Panel để hiển thị cho người sử dụng một nhóm RadioButtons có liên quan với nhau. Những chức năng không được hỗ trợ bởi điều khiển Panel Những thuộc tính sau đây không được hỗ trợ bởi điều khiển Panel: BorderStyle property BackGroundImage property AutoScroll property 2.13.11 Sử dụng các điều khiển HScrollBar và VScrollBar Các điều khiển HScrollBar và VScrollBar cho phép bạn thêm khả năng cuộn vào những thành phần mà không được hỗ trợ cuộn theo mặc định. Những control được điều khiển bởi vài thuộc tính. Danh sách sau đây chứa các thuộc tính và những ý nghĩa của chúng. - Minimum: Giá trị của điều khiển khi thanh cuộn bị giới hạn bên trái của HscrollBar hoặc ở trên đỉnh của VscrollBar. - Maximum: Đây là giá trị lớn nhất có thể xảy ra của thanh cuộn. Ghi nhớ một điều là thuộc tính Value của thanh cuộn khi thanh cuộn được kéo dọc suốt đường về phía phải của HScrollBar hay xuống đáy của VScrollBar là không bằng thuộc tính Maximum. Thuộc tính Value sẽ bằng giá trị Maximum nếu thoả công thức: Maximum – LargeChange + 1 - SmallChange: ở đây, giá trị tăng dần được dùng khi người sử dụng kích vào một trong những nút mũi tên. - LargeChange: Đây là giá trị tăng dần được dùng khi người sử dụng kích vào thanh cuộn điều khiển trên mọi cạnh của thanh cuộn. - Value: Giá trị hiện tại của thanh cuộn. Giá trị này miêu tả vị trí của đỉnh của thanh cuộn HScrollBar và cạnh trái của thanh cuộn VscrollBar. Một sự kiện valueChanged được thực thi khi thuộc tính Value thay đổi. Bẫy lỗi của sự kiện này là để thực hiện hoạt động nào đó, như sự thay đổi vị trí của một điều khiển, khi giá trị của thanh cuộn thay đổi. Mã sau đây trình bày việc xử lý sự kiện ValueChanges như thế nào: C# private void hScrollBar1_ValueChanged(object sender, System.EventArgs e) { this.label1.Text = string.Format("Scroll Bar Value: {0}", this.hScrollBar1.Value); } Hình 2.20 cho thấy một ứng dụng với một điều khiển HScrollBar được liên kết với một điều khiển Label. Những điều khiển Label hiển thị Value của HScrollBar. Khi bạn di chuyển thanh cuộn, thì nhãn được cập nhật với giá trị mới. Trong ví dụ mẫu này thì giá trị Minimum là 0, Maximum là 100, SmallChange là 10, và LargeChange là 20. Mã đầy đủ cho ví dụ mẫu này có thể được tìm thấy trong danh sách mã của cuốn sách này. Hình 2.20 : Một ứng dụng mẫu sử dụng HscrollBar 2.13.12 Sử dụng điều khiển ImageList Điều khiển ImageList là một điều khiển không đồ hoạ, nó chứa những hình ảnh. Những điều khiển .NET Compact Framework khác sử dụng điều khiển ImageList để khôi phục những ảnh chúng cần hiển thị Những hình ảnh có thể được thêm vào điều khiển ở lúc thiết kế cũng như khi thực hiện. Để thêm một ImageControl cho một form, thì ta kéo một ImageControl từ ToolBox đến form ứng dụng trong Form Designer. Bây giờ kích vào nút ba chấm bên cạnh thuộc tính Images trong cửa sổ Properties. Việc làm này sẽ đưa ra cửa sổ Image Collection Editor ( Như ta nhìn thấy trong hình 3.17). Sử dụng Image Collection Editor để thêm những hình ảnh cho ImageList. Quan trọng chú ý rằng những ảnh sẽ được thay đổi kích thước đến 16 X 16 pixel theo mặc định. Bạn có thể đặt thuộc tính ImageSize nếu bạn muốn những hình ảnh sẽ được thay đổi kích thước khác nhau. Ngoài ra, những hình ảnh này cũng được đưa vào trong file resource cho ứng dụng. Những ảnh cũng có thể được nhập vào ở thời gian thực hiện. Điều khiển ImageList trình bày một thuộc tính Images, nó đại diện cho danh sách của những hình ảnh được lưu giữ trong điều khiển. Thuộc tính Images cung cấp phương thức Add cho phép bạn thêm những hình ảnh vào danh sách của những hình ảnh. Điều thú vị là phương thức này sẽ thêm ảnh vào đầu danh sách (chỉ số là 0) - không phải là vào cuối danh sách như những phương thức khác. Phương thức Add cũng có thể chấp nhận một System.Drawing.Icon hay một System.Drawing.Image. Code dưới đây trình bày việc tải một hình ảnh từ file resource của assembly C# BitMap image = new BitMap(Assembly.GetExecutingAssembly().GetManifestResourceStream("image1.jpg"); ImageList imgList = new ImageList(); imgList.Images.Add(image); 2.13.13 Sử dụng điều khiển PictureBox Điều khiển PictureBox được sử dụng để hiển thi một ảnh. Nó có nhiều chức năng bị hạn chế. Và nó luôn luôn hiển thị ảnh ở góc trên, bên trái của điều khiển. Điều khiển PictureBox không cung cấp bất kỳ một cách nào để thay đổi kích thước của ảnh. Điều khiển PictureBox trình bày thuộc tính Image, cái mà trình bày ảnh hiện thời để điều khiển sẽ hiển thị. Có ba cách để đưa một ảnh vào trong điều khiển PictureBox: - Một ảnh có thể được đưa vào PictureBox bằng cách tải ảnh từ một file. Code dưới đây trình bày cách làm nó như thế nào: C# pictureBox1.Image = new Bitmap(@"\Program Files\PictureBoxControl\tinyemulator_content.jpg"); Khi tải một ảnh bằng cách này bạn cần phải thêm ảnh vào đối tượng Visual Studio .NET của bạn và đặt thuộc tính Build Action trong cửa sổ Properties cho Content . Khi ứng dụng của bạn được triển khai hoặc khi một file CAB được xây dựng thì sẽ bao gồm cả ảnh. - Một ảnh cũng có thể được tải từ file resource của ứng dụng của bạn. Đầu tiên thêm ảnh vào dự án Visual Studio .NET của bạn và đặt thuộc tính Build Action cho Embedded Resource. Việc làm này sẽ tải ảnh vào trong file resource của ứng dụng. Bạn không cần triển khai file ảnh với ứng dụng. Mã sau đây trình bày việc làm thế nào để thêm một điều khiển PictureBox với một ảnh được định vị trong file resource: C# pictureBox1.Image = new Bitmap(Assembly.GetExecutingAssembly(). GetManifestResourceStream("PictureBoxControl.tinyemulator_res.jpg")); - Cuối cùng bạn có thể tải một điều khiển PictureBox với một ảnh được định vị trong điều khiển ImageList như ta thấy trong mục “sử dụng điều khiển ImageList”. Một sự thuận lợi khi sử dụng một điều khiển ImageList là bạn có thể sử dụng điều khiển ImageList để thay đổi kích thước ảnh trước khi tải nó vào trong một điều khiển PictureBox . Theo mặc định tất cả các ảnh được tải nằm trong ImageList được thay đổi kích thước còn 16 X 16. Bạn có thể thay đổi kích thước bằng cách đặt thuộc tính ImageList.ImageSize theo kích thước mong muốn. Thay đổi thuộc tính ImageSize sẽ ảnh hưởng đến tất cả ảnh trong ImageList. Mã sau đây trình bày việc tải một điều khiển PictureBox thông qua điều khiển ImageBox như thế nào: C# // resize the image imageList1.ImageSize = new System.Drawing.Size(92, 156); // load the resized image pictureBox1.Image = imageList1.Images[0]; Hình 2.21 hiển thị một ứng dụng đang chạy trên bộ mô phỏng Pocket PC mà cho phép người sử dụng tải một PictureBox từ một file trên file hệ thống, file resource của ứng dụng hoặc một ImageList. Hình 2.21: Đây là một ứng dụng sử dụng điều khiển PictureBox đang chạy trên bộ mô phỏng Pocket PC 2002. 2.13.15. Sử dụng điều khiển ListView Điều khiển ListView tương tự như điều khiển ListBox, trong điều khiển ListView có thể hiển thị một mục chọn cho người sử dụng ở một boxlike UI. Điều khiển ListView bổ sung thêm chức năng qua ListBox. Ngoài những mục văn bản rõ ràng, đơn giản, điều khiển ListView cũng có thể trình bày những ảnh và những mục chọn mức dưới mà thêm chi tiết về mục chọn. Những mục chọn trong một ListView có thể được hiển thị trong bốn khung nhìn khác nhau:Details view, LargeIcon view, List view, và SmallIcon view. Điều khiển ListView trình bày thuộc tính View mà nó miêu tả khung nhìn hiện thời. Thuộc tính View của kiểu System.Windows.Forms.View, là một bảng liệt kê. Danh sách sau đây mô tả những hàm thành phần của bảng liệt kê View và chúng ảnh hưởng tới điều khiển ListView như thế nào . Mục chọn Details xuất hiện trên các dòng riêng biệt, với một số thông tin cho mục chọn được sắp xếp trong các cột. Những mục chọn LargeIcon sẽ đưa ra các Icon lớn cùng với nhãn ở dưới. Những mục chọn SmallIcon sẽ đưa ra các Icon nhỏ cùng với nhãn ở phía bên phải của các Icon. Những mục chọn List sẽ đưa ra các Icon nhỏ cùng với nhãn ở phía bên phải của các Icon. Những mục chọn được sắp xếp trong các cột, nhưng nó không được hiển thị ở đầu cột. Khi thuộc tính View đặt là Details thì ListView có thể hiện thị những mục chọn ở phía dưới, đó là hoạt động thêm thông tin có liên quan đến mục chọn. Khi ListView đặt ở chế độ Details thì các mục chọn được xuất hiện thành một danh sách, được trình bày thành bảng với mỗi hàng được ngăn cách trong các cột. Cột đầu tiên chứa đoạn văn bản và biểu tượng tuỳ chọn. Những cột tiếp theo chưa đoạn text của những mục chọn phía dưới. Hình 2.22 trình bày một ví dụ của ListView đang chạy trên bộ mô phỏng Pocket PC. Hình 2.22: Đây là một ứng dụng sử dụng điều khiển ListView đang chạy trên bộ mô phỏng Pocket PC 2002. Thêm các cột cho ListView Các cột có thể được thêm vào cho ListView ở thời điểm thiết kế hoặc ở thời điểm thực thi. Để thêm các cột vào ListView ta làm bằng cách thêm các đối tượng ColumnHeader cho thuộc tính collection cho Columns của.ListView. Những cột này chỉ được hiển thị khi ListView ở chế độ Details. Code dưới đây sẽ trình bày việc làm thế nào để thêm các cột cho điều khiển cho ListView. C# System.Windows.Forms.ColumnHeader columnHeader1 = new ColumnHeader(); System.Windows.Forms.ColumnHeader columnHeader2 = new ColumnHeader(); System.Windows.Forms.ColumnHeader columnHeader3 = new ColumnHeader(); columnHeader1.Text = "Name"; columnHeader2.Text = "Purpose"; columnHeader3.Text = "Availability"; listView1.Columns.Add(columnHeader1); listView1.Columns.Add(columnHeader2); listView1.Columns.Add(columnHeader3); Ngoài ra, các cột cũng có thể được thêm vào cho ListView ở thời điểm thiết kế. Đầu tiên ta kéo một điều khiển ListView từ ToolBox vào trong form ứng dụng. Tiếp theo ta kích vào nút ba chấm ở bên cạnh tên thuộc tính, trong của sổ Properties. Việc làm này sẽ đưa ra cửa sổ ColumnHeader Collection Editor (như ta thấy trong hình 3.24). Sử dụng các nút Add và Remove để thay đổi danh sách của các đối tượng ColumnHeader trong điều khiển ListView. Hình 2.23: Cửa sổ ColumnHeader Collection Editor. Thêm những mục chọn cho điều khiển ListView Sau khi thêm các cột cho điều khiển ListView ta có thể thêm các mục chọn. Lớp ListViewItem mô tả những item trong một điều khiển ListView và lớp ListViewSubItem mô tả những item ở phía dưới có liên quan đến ListViewItem. Lớp ListViewItem trình bày thuộc tính collection SubItems, là cái mà mô tả danh sách những item ở phía dưới có liên quan đến một item. Một đối tượng ListViewItem có thể hiển thị một ảnh cùng với đoạn text. Một ImageList phải được sử dụng để kết hợp một ảnh với một đối tượng ListViewItem. Điều khiển ListView trình bày hai thuộc tính: SmallImageList và LargeImageList. LargeImageList.ImageList chứa ảnh để sử dụng khi thuộc tính View thiết đặt là View.LargeIcon. SmallImageList.ImageList chứa ảnh để sử dụng khi thuộc tính View thiết đặt cho bất kì cái gì khác với View.LargeIcon. Ngoài ra, những đối tượng ListViewItem cũng có thể được thêm vào ở thời điểm thiết kế. Đầu tiên ta kích vào điều khiển ListView, cái mà sẽ chứa những item. Nếu những điều khiển ImageList đã được định hình cho điều khiển ListView thì ta gán những điều khiển ImageList cho thuộc tính LargeImageList và thuộc tính SmallImageList trong của sổ Properties. Tiếp theo ta kích vào nút ba chấm bên cạnh thuộc tính Items trong của sổ Properties. Một cửa sổ ListViewItem Collection Editor sẽ xuất hiện (như ta thấy trong hình 2.24). Ta sử dụng nút Add và nút Remove để thay đổi nhũng item ở trong ListView. Đặt thuộc tính ImageIndex nếu một ImageList đã được định hình cho ListView. Nếu bạn cần thêm những mục chọn phía dưới cho các đối tượng ListViewItem thì bạn kích vào nút ba chấm bên cạnh thuộc tính SubItems trong cửa sổ soạn thảo. Khi đó cửa sổ ListViewSubItem Collection Editor sẽ xuất hiện (như hình 2.24). Và ta lại sử dụng nút Add và nút Remove để thay đổi collection của nhứng item phía dưới. Hình 2.24: Cửa sổ ListViewItem Collection Editor Hình 2.25: Cửa sổ ListViewSubItem Collection Editor. Chương 3: Tìm hiểu ADO.NET trên .NET Compact Framework 3.1 Giới thiệu ADO.NET trên .NET Compact Framework ADO.NET là tên dựa vào tập hợp các lớp, được sử dụng cho việc truy cập cơ sở dữ liệu trong lập trình .NET toàn cầu. Tập hợp các lớp sẵn có trong thế giới ADO.NET là rất nhiều và có thể chiếm ưu thế. Tuy nhiên, việc xử lý dữ liệu và ngay cả những kết nối đơn giản tới các máy chủ cơ sở dữ liệu từ xa có thể được thực hiện với một vài dòng code. Chương này được dành cho việc trình bày việc làm thế nào để thao tác dữ liệu cục bộ trên thiết bị. Nó đặt nền tảng cho các chương sau mà có liên quan đến ADO.NET 3.2. Lưu dữ liệu với DataSet DataSet là lớp khung cơ bản cho thao tác dữ liệu với .NET Compact Framework. DataSet có thể được hiểu như một dụng cụ cơ sở dữ liệu quan hệ nhỏ trong chính nó. Nó lưu giữ các bảng trong bộ nhớ và được tổ chức thành các bảng, các hàng, và các cột, và nó cho phép những người phát triển thực hiện những thao tác cơ sở dữ liệu chuẩn, như việc thêm và loại bỏ dữ liệu, sắp xếp, và kiểm tra những ràng buộc. Làm việc với .NET Compact Framework khó hơn làm việc với desktop .NET Framework, bởi vì có nhiều sự quá tải (overloads) không thể tìm thấy trên .NET Compact Framework và nó dễ dàng làm cho quá trình hoạt động lộn xộn, làm cho quá trình thực thi kéo dài. Toàn bộ chiến lược để xử lý dữ liệu trong lập trình ADO.NET là làm đầy một DataSet từ một cơ sở dữ liệu lớn, bao gồm cả việc lưu dữ liệu trong DataSet , và sau đó viết lại bất kỳ sự thay đổi nào cho cơ sở dữ liệu. Chương này bàn luận việc làm thế nào để đưa dữ liệu vào DataSet bởi việc chèn dữ liệu theo chương trình và để thực hiện những thao tác đơn giản trên dữ liệu. 3.2.1 Tìm hiểu bên trong DataSet: DataTables, DataRows, và DataColumns. DataSet chứa một hoặc nhiều DataTable. Mỗi DataTable tương ứng với một bảng trong cơ sở dữ liệu quan hệ. Nó có một tập hợp các DataRow, và mỗi DataRow có một tập các DataColumn mà nó thực sự lưu giữ dữ liệu. Để tạo ra các DataSet, DataTable, và DataColumn dễ dàng và dễ làm việc với chúng, ta đặt tên cho chúng. Hình 6.1 là sơ đồ khối miêu tả toàn bộ cấu trúc của một DataSet lưu dữ liệu cho một PhoneBook đơn giản. Hình 6.1: Đây là một DataSet mô tả cấu trúc của một phone book. Bạn có thể sử dụng một DataTable để lưu dữ liệu được kết hợp với một bảng, nhưng DataSet cung cấp các phương thức và các thuộc tính mà có thêm tiện ích và thực sự tạo ra một cơ sở dữ liệu quan hệ thu nhỏ trong bộ nhớ. Ví dụ, với DataSet bạn có thể làm tất cả những việc được nêu ở dưới đây: Thao tác với thông tin ở trong một DataSet như một cơ sở dữ liệu quan hệ nhỏ. Chẳng hạn, bạn có thể thiết lập những mối quan hệ cha - con, cập nhật và xóa, và tạo ra những cột dữ liệu mà được tính toán từ những trường dữ liệu khác. Save hoặc load các nội dung của tất cả các DataTable vào một file XML với chỉ một dòng lệnh Nó thông qua bộ máy SQL CE, bộ máy này sẽ giúp chúng ta đưa vào nó các bảng từ cơ sở dữ liệu quan hệ được lưu trữ trên thiết bị hoặc thay thế bằng dữ liệu từ máy chủ từ xa. Thông qua nó, SQL cung cấp để đưa vào với các bảng từ một máy chủ từ xa.. Nhận ở DataSet, cái mà trả về những giá trị của các Web service, hoặc thông qua DataSet để trở lại một Web service 3.2.2 Đưa dữ liệu vào trong một DataSet Để đưa dữ liệu mới vào một DataSet, chúng ta cần thực hiện theo những bước sau: Nhận một tên cho DataTable bên trong DataSet mà bạn muốn thêm hàng dữ liệu mới trong nó. Nếu cần thiết ta có thể tạo mới một DataTable. Tập hợp các DataTable mà DataSet quản lý có thể được sử dụng thông qua thuộc tính DataSet.Tables. Nếu bạn phải tạo một DataTable mới và thêm nó vào tập hợp DataSet.Tables thì bạn sẽ đi theo những bước sau (thông thường, bạn sẽ thêm dữ liệu cho một bảng đã có sẵn, vì vậy bạn có thể bỏ qua các bước này): Tạo một DataTable qua cấu trúc DataTable Tạo một các DataColumn và thêm chúng vào tập hợp DataTable.Columns. Với mỗi DataColumn mới, bạn phải chỉ định tên cho cột và kiểu dữ liệu của nó. Thêm DataTable mới cho tập hợp DataSet.Table bằng cách gọi đến phương thức .Add của nó. Tạo một DataRow mới bằng cách yêu cầu DataTable tạo nó ra cho bạn. Ví dụ, để tạo một hàng mới cho DataTable đầu tiên trong một DataSet ta sử dụng câu lệnh l_newRow = l_DataSet. Tables[0].NewRow. Ngoài ra, bạn cũng có thể chỉ định bảng bằng tên, ví dụ : l_newRow = l_DataSet.Tables["Customers"].NewRow DataRow mới được tự động tạo ra các cột tương ứng với bảng đã được tạo. Đưa các giá trị vào trong các cột của DataRow Thêm DataRow mới vào tập hợp Rows của DataTable đã được tạo. Ví dụ : l_DataSet.Tables[0].Rows.Add(l_newRow);. Sau khi chúng ta đã có tất cả các dòng như mong muốn, ta gọi DataSet.AcceptChanges để chấp nhận sự thay đổi. Để huỷ bỏ tất cả việc thêm mới dữ liệu ta gọi phương thức DataSet.RejectChanges 3.2.3. Xây dựng một DataSet lưu giữ một Phone Book Để hiểu việc làm thế nào để tạo một DataSet có khả năng lưu trữ dữ liệu quan hệ, chúng ta sẽ xem một vài dòng code mẫu của ứng dụng PhoneBook. Đây là ứng dụng mẫu được giải thích rất chi tiết trong mục tiếp theo, cài đặt một DataSet có khả năng lưu trữ một phone book mẫu. DataSet lưu trữ một DataTable đơn, bảng này được thiết lập với hai DataColumn, một để lưu tên và một lưu số điện thoại. Đoạn mã sau mô tả năm bước cần thiết để thêm dữ liệu cho một DataSet, bao gồm cả việc tạo một bảng mới. Đoạn code: Tạo và lưu một DataSet C# DataSet l_DataSet = new DataSet(); // Create a DataTable that holds a "Name" and a "PhoneNumber" DataTable l_newTable = new DataTable("Phone Contacts"); l_newTable.Columns.Add(new DataColumn("Name", typeof(System.String))); l_newTable.Columns.Add(new DataColumn("PhoneNumber", typeof(System.String))); // Add the DataTable to the DataSet's table collection l_DataSet.Tables.Add(l_newTable); // Now put a few names in... // GEORGE WASHINGTON DataRow l_newRow = l_DataSet.Tables[0].NewRow(); l_newRow[0] = "George Washington"; l_newRow[1] = "555 340-1776"; l_DataSet.Tables[0].Rows.Add(l_newRow); // BEN FRANKLIN l_newRow = l_DataSet.Tables[0].NewRow(); l_newRow["Name"] = "Ben Franklin"; l_newRow["PhoneNumber"] = "555 336-3211"; l_DataSet.Tables[0].Rows.Add(l_newRow); // Commit the changes l_DataSet.AcceptChanges(); 3.2.4. Trích dữ liệu từ một DataSet Trích dữ liệu từ một DataSet đơn giản như việc truy nhập vào DataTable trong tập hợp DataSet.Tables và xem xét các hàng mong muốn trong bảng. Mỗi hàng có một chỉ số làm cho nó dễ dàng truy nhập vào các cột mong muốn. Chỉ số đầu tiên là số 0, như trong ví dụ: l_DataSet.Tables[0].Rows[0][0]: truy cập vào cột đầu tiên trong dòng đầu tiên của DataTable đầu tiên. l_DataSet.Tables[0].Rows[0][9]L: Truy cập vào cột thứ 10 trong hàng đầu tiên của DataTable đầu tiên. l_DataSet.Tables[0].Rows[29][9]: Truy cập vào cột thứ 10 trong hàng thư 30 của DataTable đầu tiên. 3.2.5. Trích dữ liệu của PhoneBook từ một DataSet Đoạn code mẫu sau đây được đưa ra từ ứng dụng PhoneBook mẫu. Nó là một vòng lặp đi qua tất cả các hàng trong DataTable đầu tiên trong một DataSet và đưa các giá trị DataColumn thứ 0 và thứ 1 vào trong một ListBox. C# for (int i = 0; i < phonebookEntriesDataSet.Tables[0].Rows.Count; i++) { this.listBox1.Items.Add( phonebookEntriesDataSet.Tables[0].Rows[i][0] + " " + phonebookEntriesDataSet.Tables[0].Rows[i][1]); } 3.2.6. Thay đổi dữ liệu trong một DataSet Để thay đổi dữ liệu được lưu trữ bên trong DataSet, bạn truy cập vào DataColumn mà bạn muốn thay đổi và đặt cho nó một giá trị mới. khi tất cả các thay đổi được kết thúc, bạn gọi hàm AcceptChanges để chấp nhận sự thay đổi đó. Ví dụ, đoạn mã sau đây sẽ thiết đặt cột thứ hai trong hàng đầu tiên của bảng đầu tiên trong tập hợp DataSet thành một số ngẫu nhiên được cung cấp bởi l_randomGenerator. C# // Column 1 is the phone number. // | // V m_phonebookDS.Tables[0].Rows[0][1] = randomGenerator.Next().ToString(); Thay đổi bằng cách sử dụng chỉ số tên, cách này chậm hơn trong .NET Compact Framework khi lượng lớn dữ liệu là phức tạp: C# m_phonebookDS.Tables["Phone Contacts"].Rows[0]["PhoneNumber"] = l_randomGenerator.Next().ToString(); 3.2.7. Gỡ những lỗi thông thường có liên quan đến DataSet Lỗi chung nhất mà người dùng hay gặp phải khi họ cố gắng truy nhập hoặc thay đổi một đối tượng trong một DataSet, như là một DataColumn hoặc DataRow mà nó không tồn tại. Ví dụ như, nếu một DataSet chỉ có hai bảng thì đoạn code này có thể bị lỗi bởi vì tập hợp DataSet.Tables sử dụng chỉ số 0: C# m_phonebookDS.Tables[2].Rows[0][1] = l_randomGenerator.Next().ToString(); Trong tình hình này thì một ngoại lệ chung nhất mà người phát triển sẽ thấy là IndexOutOfRangeException. 3.3 Tìm hiểu về các ràng buộc dữ liệu DataSet cho phép bạn chỉ định những quy tắc riêng biệt mà dữ liệu lưu trữ bên trong tập DataSet.Tables phải theo. Lớp cơ bản Constraint chỉ rõ những quy tắc mà dữ liệu bên trong một DataTable phải theo để duy trì tính toàn vẹn cho CSDL. Hai lớp được kế thừa từ lớp Constraint trình bày sự giới hạn riêng mà dữ liệu phải theo. UniqueConstraint chỉ rõ một giá trị đặc biệt cho một DataColumn duy nhất trong bảng. ForeignKeyConstraint được sử dụng để tạo sức mạnh cho hành động khi thay đổi hoặc xoá cột khoá chính của một bảng. Bởi vì ForeignKeyConstraint được dùng để thay thế cho mô hình quan hệ cha - con giữa các bảng. 3.3.1 Thêm các ràng buộc cho một DataSet Mỗi DataTable được lưu trữ trong tập DataSet.Tables chứa một ConstraintCollection trong thuộc tính Constraints. Ví dụ, để truy nhập ConstraintCollection trong bảng đầu tiên của một DataSet, ta dùng đoạn mã sau: C# m_phonebookDS.Tables[0].Constraints Những bước tạo và khởi tạo những sự ràng buộc khác theo loại ràng buộc mà bạn đang thử để tạo ra. Mỗi một lần ràng buộc được tạo ra và khởi tạo, bạn phải thực hiện những bước này để làm cho nó hoạt động được: Các bước tạo và khởi tạo ràng buộc: Thêm ràng buộc cho tập hợp Constraints của các bảng thích hợp. Thiết đặt cờ lệnh DataSet.EnforceConstraints là true để yêu cầu ràng buộc. khi bạn thiết đặt cờ lệnh trở lại là true thì mỗi ràng buộc trong mỗi tập hợp DataTable.Constraints được kiểm tra, và đưa ra một ngoại lệ nếu kiểm tra bị lỗi. Thêm một UniqueConstraint Để thêm một UniqueConstraint cho một DataSet, ta làm theo các bước sau: 1. Tạo một UniqueConstraint bằng cách sử dụng một trong bốn khởi tạo trên .NET Compact Framework. Mỗi một khởi tạo được thảo luận chi tiết dưới đây : - UniqueConstraint(String name, DataColumn col): tạo một UniqueConstraint với tên riêng mà phải là duy nhất trong một DataColumn đơn. - UniqueConstraint(DataColumn col)tạo một UniqueConstraint mà nó là duy nhất trên một DataColumn đơn. - UniqueConstraint(String name, DataColumn[] cols): tạo một UniqueConstraint mà nó là duy nhất của nhiều cột trong một hàng. Các cột này được đặt rất ngẫu nhiên như một mảng . - UniqueConstraint(DataColumn[] cols) : Tương tự như trên trừ UniqueConstraint là không tên. - UniqueConstraint(String name, string[] colNames, bool isPrimaryKey): Đây là khởi tạo chung thứ năm, chỉ có ích trong môi trường Smart Device Extensions. 2. Thêm UniqueConstraint cho tập hợp Constraints của DataTable mong muốn. 3. Thiết đặt là true để mở ràng buộc. Cần lưu ý với DataSet.EnforceConstionts Khi DataSet.EnforceConstraints là true thì bạn sẽ thấy một ngoại lệ ở bất cứ thời điểm nào mà bạn đưa vào, xoá, hoặc cập nhật dữ liệu trong DataSet. Một ngoại lệ được đưa vào tuỳ theo những chi tiết của những ràng buộc trong DataSet. Nếu một ngoại lệ là thrown, bạn có thể trở lại những sự thay đổi bạn đã làm bằng cách bắt ngoại lệ và gọi DataSet.RejectChanges(). 3.3.3 Ngăn chặn giá trị Null trong một DataColumn Thuộc tính DataColumn.AllowDBNull rất có ích cho việc không công nhận một DataColumn có giá trị DBNull. Nếu bạn tạo một DataRow mới và không gán một giá trị cho một trong số các cột, nó sẽ nhận giá trị mặc định là DBNull. Đoạn code mẫu dưới đây được lấy ra từ ứng dụng PhoneBook mẫu. Đoạn code mẫu này không công nhận trường Name của PhoneBook vì tồn tại DBNull. C# l_newTable.Columns["Name"].AllowDBNull = false; Nếu một DataColumn mà có AllowDBNull là false được thiết lập cho DBNull, thì một ngoại lệ System.Data.NoNullAllowed được đưa ra khi hàng mới được thêm vào cho một DataTable lưu vào trong DataSet. Ví dụ, đoạn code dưới đây thực hiện việc thêm vào một hàng tại cột Name mà chưa bao giờ thiết đặt, và vì vậy việc thực hiện đoạn code này sẽ đưa ra một ngoai lệ System.Data.NoNullAllowed . C# DataRow l_newRow = m_phonebookDS.Tables[0].NewRow(); l_newRow[0] = "Violator" l_newRow[1] = "5555587"; // This is going to throw an exception because the "Name" // DataColumn was never set, so it is DBNull, and that is // not allowed for the DataColumn m_phonebookDS.Tables[0].Rows.Add(l_newRow);] 3.4 Thiết lập cho các trường tự động tăng giá trị Khi một hàng mới được thêm vào cho một DataTable, thì hàng rỗng được thêm vào bằng cách gọi phương thức DataTable.NewRow. DataTable biết mô hình của hàng mà nó phải tạo ra và khởi tạo hàng mới để phù hợp với mô hình. Điều đó có nghĩa là hàng mới lưu trữ phải có DataColumn cùng với những kiểu dữ liệu chính sác sằn sàng cho bạn để đặt dữ liệu. Thuộc tính DataColumn.AutoIncrement có thể được thiết đặt chỉ cho DataTable để thiết đặt giá trị cho một DataColumn tự đông tăng giá trị khi một hàng mới được tạo. Đây là một đặc trưng có ích nhất của DataColumns, nó rất hữu dụng khi dùng làm trường khoá trong một bảng, từ đó khoá có thể tự động được tạo cho bạn. Có ba thuộc tính quan trọng trong DataColumn liên quan đến các trường tự động tăng giá trị: DataColumn.AutoIncrement thiết đặt là true sẽ cho DataColumn tự động tăng. DataColumn.AutoIncrementSeed Giá trị bắt đầu cho tự động tăng. DataColumn.AutoIncrementStep số lượng các bước tăng cho mỗi giá trị mới. Nếu DataColumn là một cột tính toán, thì cố gắng thiết đặt nó như một cột tự động tăng và sẽ gây ra một ngoại lệ ArgumentException. Nếu kiểu dữ liệu của DataColumn không phải là kiểu Int16, Int32, hoặc Int64,thì nó buộc phải chuyển về một kiểu Int32. Điều này có thể là nguyên nhân mất độ chính xác nếu kiểu dữ liệu là kiểu số thực - con trỏ (floating-point). Nếu DataColumn có kiểu dữ liệu là string thì thiết đặt nó ở chế độ tự động tăng sẽ ép kiểu dữ liệu của DataColumn thành kiểu integer. Ví dụ tạo trường tự động tăng giá trị Đoạn code mẫu được lấy ra từ ứng dụng PhoneBook mẫu. Ở trong đoạn code này ta thiết đặt thuộc tính AutoIncrement của ContactID DataColumn trong bảng có tên là l_newTable. Giá trị bắt đầu là 10, và giá trị bước nhảy là 5. C# l_newTable.Columns["ContactID"].AutoIncrement = true; l_newTable.Columns["ContactID"].AutoIncrementSeed = 10; l_newTable.Columns["ContactID"].AutoIncrementStep = 5; 3.5. Mô hình dữ liệu quan hệ với DataSet Bây giờ bạn sẽ tìm hiểu đầy đủ về việc DataSet lưu trữ một DataTable, truy nhập dữ liệu, và giám sát việc thi hành một số mẫu của những ràng buộc dữ liệu. Trong mục này chúng ta xây dựng dựa vào kiến thức đã biết và học thực hiện những thao tác về cơ sở dữ liệu quan hệ chung với dữ liệu được lưu trũ trong DataSet. 3.5.1 Xuất phát từ những giá trị DataColumn cùng với biểu thức và các trường tính toán. Những giá trị của một DataColumn có thể được tính toán dựa trên giá trị DataColumn khác trong cùng DataRow. Để làm điều này, ta sử dụng thuộc tính DataColumn.Expression để mô tả giá trị tính toán của DataColumn. Thuộc tính Expression là một giá trị kiểu string, nó mô tả việc tính toán xuất phát từ giá trị của DataColumn. Cú pháp của biểu thức rất nhiều và được hỗ trợ một tập hợp rất phong phú về các phép tính toán học và chuỗi. Bảng 6.1 trình bày tất cả các toán tử của biểu thức mà được hỗ trợ bởi .NET Compact Framework. Bảng 3.1. Những toán tử của biểu thức được hỗ trợ bởi Framework Toán Tử Chức Năng Sum Tính tổng của các đối số Avg Tính trung bình các đối số Min Lựa chọn giá trị nhỏ nhất của các đối số Max Lựa chọn giá trị lớn nhất của các đối số +, -, *, / Các phép tính: cộng, trừ, nhân, chia % Chia lấy số dư (phần còn lại của phép chia) + Ghép chuỗi Ví dụ tạo biểu thức. Cách dễ dàng nhất để hiểu “việc tạo một biểu thức như thế nào?” là xem một ví dụ. Cho ví dụ đẩu tiên của chúng ta hãy xem một DataTable được gọi là l_newTable mà nó có ba cột được đặt tên là: FirstName, LastName, và FullName. Mục đích của việc tạo một biểu thức mà đặt cột tên là FullName để ghép chuỗi của cột FirstName và cột LastName lại với nhau. Code sau đây sẽ trình bày việc làm này: C# l_newTable.Columns["FullName"].Expression = "FirstName + ' ' + LastName"; Cho ví dụ thứ hai, ta sẽ xem một DataTable được đặt tên là l_newTable.Chúng tôi muốn đưa cột TotalPrice vào để lưu giá trị của cột MSRP trừ đi giá trị của cột Discount. C# l_newTable.Columns["TotalPrice"].Expression = "MSRP - Discount"; ví dụ cuối cùng, l_newTable được xem là một DataTable với bốn cột: FinalGrade, Exam1, Exam2, và Exam3. Chúng tôi muốn đặt giá trị của cột FinalGrade bằng giá trị trung bình của Exam1, Exam2, và Exam3, như đoạn code sau: C# l_newTable.Columns["FinalGrade"].Expression = "Avg(Exam1, Exam2, Exam3)"; 3.5.2 Biểu diễn mối quan hệ Cha – Con tring một DataSet Thành phần chủ yếu của một CSDL quan hệ là các bảng với các hàng và khả năng tạo một mối quan hệ Cha – Con, hoặc một mối quan hệ giữa hai bảng với nhau. Một mối quan hệ giữa hai bảng được làm bằng cách liên kết hai bảng bởi một hoặc nhiều cột dữ liệu được làm khoá chính. Trong bảng cha, khoá chính (primary key) là duy nhất cho tất cả các hàng trong bảng. Các hàng trong bảng con có một cột gọi là khoá ngoại (foreign key), nó không phải là duy nhất trong bảng con. Nó nhằm vào hàng tương ứng trong bảng cha. Ví dụ, xem bảng 3.2, một bảng cha lưu thông tin chính về ngươi bệnh cho một văn phòng của thầy thuốc. Table 3.2. MainContactTable COLUMN NAME DATA TYPE CustID Integer, PRIMARY KEY FirstName String LastName String Bảng 3.3: Một bảng con lưu ngiên cứu về cholesterol. Table 3.3. CholesterolTable COLUMN NAME DATA TYPE CustID Integer, FOREIGN KEY Reading1 Decimal Reading2 Decimal Reading3 Decimal Average Decimal Trong bảng CholesterolTable thì cột CustID có là cột duy nhất tham chiếu tới bảng MainContactTable. Bảng 3.4 và 3.5 cho thấy mối quan hệ cha – con khi lưu trữ. Table 3.4. MainContactTable CustID FirstName LastName 001 George Washington 002 Ben Franklin 003 Alexander Hamilton Table 3.5. CholesterolTable CustID Reading1 Reading2 Reading3 Average 001 87 78 66 77.0 001 99 54 89 80.667 002 90 88 55 77.667 Trong bảng cha – con ở ví dụ này, có hai mục (bản ghi) trong bảng CholesterolTable cho George Washington và một mục cho Ben Franklin. Chuyện gì sẽ xảy ra nếu bản ghi của George Washington bị xoá trong bảng MainContactTable? Hệ thống phải xoá tất cả những bản ghi tương ứng trong CholesterolTable hoặc cơ sở dữ liệu sẽ bị hỏng. 3.5.3 Tạo một DataRelation cho việc biểu diễn quan hệ cha – con. Khi bạn thiết đặt một DataRelation giữa hai bảng, bạn phải chỉ định rõ DataColumn như khóa chính, khoá ngoại. Sau khi DataRelation được tạo, nó sẽ bảo đảm dữ liệu quan hệ của DataSet, như được mô tả bởi DataRelation. Ví dụ, nếu bạn xoá hàng đầu tiên từ bảng MainContactTable, thì DataRelation tự động xoá tất cả các hàng con trong CholesterolTable. Để thiết lập một DataRelation giữa hai bảng trong một DataSet, thì đầu tiên tạo một DataRelation bằng cách sử dụng hàm tạo thông qua DataColumn mà bao gồm khoá chính và khoá ngoại. Các hàm tạo trong .NET Compact Framework như sau: DataRelation(String relName, DataColumn parent, DataColumn child): tạo một tên DataRelation giữa DataColumns cha và con. DataRelation(String relName, DataColumn[] parent, DataColumn[] child): tạo một tên DataRelation giữa hai bảng bằng cách sử dụng nhiều cột cho mỗi bảng của quan hệ. DataRelation(String relName, DataColumn parent, DataColumn child, bool createConstraints): tạo một DataRelation giữa DataColumns cha và con. DataRelation(string relName, DataColumn[] parent, DataColumn[] child, bool createConstraints): tạo một DataRelation giữa hai bảng bằng cách sử dụng nhiều cột cho mỗi bảng của quan hệ, với tùy chọn rõ ràng để tạo ra những ràng buộc kết hợp với việc thi hành quan hệ. DataRelation(string relName, string parentTableName, string childTableName, string[] parentColNames, string[] childColNames, bool isNested): Là hàm tạo đã sử dụng môi trường Smart Device Extensions. Sau đó ta dễ dàng thêm DataRelation cho tập hợp DataSet.Relations. 3.5.4 Viết code để tạo một DataRelation Đây là code mẫu được lấy từ code của ứng dụng PhoneBook, nó mô tả việc sử dụng các lớp Expression và Dat

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

  • doctim hieu ve cnghe Net compact framework va lap trinh ung dung tren PC.doc