Chương I: ĐẶT VẤN ĐỀ I.1. Đưa ra bài toán Đề tài thực hiện: “Phần mềm thi trắc nghiệm tiếng anh” Cho đến nay tiếng Anh là môn học duy nhất cho phép thử nghiệm tất cả các hình thức câu hỏi trắc nghiệm mà chưa môn học nào đáp ứng được. Phần mềm ra đời dựa trên nhu cầu thực tế của việc quản lý thi trắc nghiệm hiện nay. Lưu trữ thông tin sinh viên, tạo đề thi, tạo lớp thi, quản lý điểm thi, cho sinh viên thi trực tiếp trên máy tính và có thể cho thí sinh biết ngay điểm thi sau khi thi xong. I.2. Hướng giải quyết bài toán Xây dựng một phần mềm thi trắc nghiệm trên máy tính giải quyết các vấn đề về thi trắc nghiệm. Dựa trên nền tảng ngôn ngữ CShape WPF Application. Cơ sở dữ liệu lưu trữ trong SQL server. Các vấn đề của bài toán là: - Quản lý thông tin sinh viên - Quản lý ngân hàng đề thi - Quản lý lớp thi - Quản lý điểm thi - Cho sinh viên thực hiện bài thi, lưu trữ bài thi Dữ liệu được đặt trên máy chủ của phòng máy, tất cả sinh viên từ máy tính khác connect đến máy chủ để lấy dữ liệu thực hiện bài thi. Giáo viên, quản trị có thể quản lý mọi thông tin.
1
I.3. Mục đích báo cáo Tốt nghiệp là mốc quan trọng đánh dấu sự trưởng thành về chất của bản thân mỗi sinh viên. Bài báo cáo tóm gọn những kiến thức quý báu mà em được học tập và tích lũy tại trường, cộng với kinh nghiệm cần thiết để thực hiện đồ án tốt nghiệp.
Với sự nỗ lực trong suốt thời gian qua, em mong rằng bài báo cáo tốt nghiệp này, trình bày được những khía cạnh đầy đủ và hữu ích của một phần lĩnh vực công nghệ thông tin. Lĩnh vực mà ngày nay nước ta đang chú trọng phát triển. Báo cáo là cách nhìn từ tổng quan tới chi tiết của những bài toán trong cuộc sống được giải quyết bằng cách áp dụng công nghệ thông tin. Chương II. GIỚI THIỆU CÔNG NGHỆ II.1 Công nghệ WPF 1.1. Khái niệm đầu tiên về WPF WPF là một công nghệ của microsoft hỗ trợ mạnh mẽ cho việc lập trình giao diện đồ họa trên nền Windows cho các ứng dụng trên nền tảng dotnet. WPF cung cấp hệ thống thư viện lớn mạnh hỗ trợ cho việc thiết kế giao diện, tăng cường tối đa khả năng sáng tạo của lập trình viên để tạo ra những chương trình có giao diện đẹp, thân thiện, trực quan và dễ sử dụng. Như ta thấy trong các ứng dụng hiện đại có yêu cầu rất cao trong việc thiết kế giao diện. Chương trình của bạn trước hết phải đẹp, bắt mắt, có nhiều hiệu ứng trực quan, tính năng dễ sử dụng; Đặc biệt trong kỹ nguyên công nghệ cảm ứng đa điểm và ứng dụng di động phát triển mạnh mẽ như hiện nay thì ứng dụng hỗ trợ cảm ứng và chạy trên nhiều nền tảng được người dùng đặc biệt quan tâm. Việc Apple lần đầu tiên đưa ra Iphone với công nghệ lập trình ứng dụng rất trực quan đã hướng thị hiếu con người sang một bước tiến mới và buộc các hãng sảnxuất phần mềm phải rung chuyển có những thay đổi đi để kịp xu hướng mới… WPF bắt đầu được tích hợp trong dotnet framework 3.0 trở về sau. So với việc thiết kế giao diện khi lập trình Winform bạn sẽ thấy được những ưu thế vượt trội của WPF, tính mềm dẻo trong giao diện thực thi, khả năng tùy biến cao, giảm thiểu trường hợp vỡ khung, vỡ giao diện khi thay đổi kích thước form… Trong WPF hỗ trợ nhiều control rất tiện ích có thể dễ dàng sử dụng, 2
để có một control tương tự trong winform bạn phải mất nhiều thời gian để tự thiết kế và hiệu quả đem lại không thể sánh bằng WPF. 1.2. Mục tiêu của công nghệ Microsoft đi sâu vào 3 mục tiêu: - Cung cấp một nền tảng chuẩn và thống nhất chung cho việc thiết kế giao diện người dùng cho các ứng dụng. - Tăng cường tính độc lập trong quá trình làm việc của người thiết kế và người lập trình. Mỗi bên có thể làm việc độc lập theo những chuẩn quy định trước và sẽ dễ dàng trong việc kết nối công việc với nhau. - Hướng tới nền tảng công nghệ chung nhất để xây dựng giao diện cho cả ứng dụng web và ứng dụng desktop. 1.3. Những điểm mạnh bên trong WPF WPF được tích hợp bên trong nhiều nền tảng khác nhau và đồng thời có thể xử lý tốt nhiều mảng công việc khác nhau trong khi trước đây cần phải kết hợp nhiều công nghệ riêng rẽ trong một ứng dụng để thực hiện những tác vụ khác nhau. WPF hỗ trợ xử lý giao diện, cung cấp các control từ cơ bản tới chuyên sâu, hỗ trợ mạnh mẽ cho việc xử lý text, không chỉ thế còn được tích hợp tính năng xử lý âm thành, hình ảnh, video, đồ họa 2D, 3D…
3
1.4. Khái niệm XAML trong WPF XAML ( eXtensible Application Markup Language ) là một ngôn ngữ đặc tả tương tự như XML . Trong WPF các mã thiết kế control trong C# được ánh xạ tương ứng sang XAML và mọi thứ được đơn giản hơn rất nhiều giúp người thiết kế nhanh chóng tạo ra giao diện đẹp tốn ít thời gian thiết kế. Mọi mã thiết kế trong C# đều tồn tại một mã XAML tương ứng. Như ta thấy trong lập trình winform truyền thống một người để thiết kế được giao diện tốt thì ngoài hiểu biết đồ họa, thiết kế thì cần phải biết cả C#, mức
độ biết không chỉ đơn thuần là cơ bản mà phải am hiểu tường tận từng control –cấu trúc – hoạt động… để phân tích giao diện khi có những thay đổi về kích thước, diện mạo, vị trí hay nói cách khách khi người dùng customize giao diện… phải đảm bảo không xảy ra trường hợp vỡ giao diện, control bị xếp chồng. Và tất nhiên để yêu cầu 1 người chuyên thiết kế nghiên cứu lập trình không phải là giải pháp tốt. Theo như truyền thống người thiết kế sẽ vẽ ra giao diện đồ họa dưới dạng ảnh tĩnh, sau đó cắt xén theo từng phần và gửi file ảnh cho người lập trình. Người lập trình lúc này phải thiết kế ứng dụng sử dụng ảnh nền từ người thiết kế. Mà ta thấy người thiết kế khi không am hiểu tính chất của giao diện khi lập trình sẽ dẫn đến trường hợp giao diện được vẽ ra rất khó có thể hiện thực hoặc người lập trình không làm trọn vẹn ý tưởng của người thiết kế do hạn chế bên mảng lập trình. Như vậy đã sinh ra sự bất đồng bộ trong khâu thiết kế và khâu lập trình, phát sinh nhiều khó khăn. XAML ra đời và đã giải quyết tốt vấn đề ở trên. XAML là ngôn ngữ dễ học, và bản thân WPF được hỗ trợ mạnh mẽ cho việc thiết kế giao diện. Như vậy người thiết kế sẽ làm việc trực tiếp lên giao diện thực và dễ dàng “hiện thực hóa” ý tưởng thiết kế của mình. Sau khi hoàn tất giao diện hoàn thiện sẽ được chuyển qua cho người Lập trình. Như vậy người lập trình sẽ giảm bớt được khâu thiết kế rất nặng nề. Kết quả như ta thấy vấn đề nêu trên đã được giải quyết rất ổn thỏa, khâu lập trình và thiết kế dễ dàng phối hợp với nhau trong khi khả năng làm việc độc lập được tăng cao. Để thiết kế giao diện ứng dụng WPF ngoài Visual Studio Microsoft còn có công cụ chuyên dụng chỉ dành chi việc thiết kế: Microsoft Expression Interactive Designer. Mối quan hệ giữa người thiết kế và người lập trình được biểu thị thông qua quan hệ giữa Microsoft Expression Interactive Designer <-
4
>XAML<->Visual
Studio.
1.5. Thống nhất lập trình giao diện trong ứng dụng windows và ứng dựng web Nếu so sánh giao diện giữa ứng dụng web và ứng dụng windows thì ta thấy mỗi cái đều có điểm mạnh riêng. Ứng dụng desktop thì chắc chắn sẽ mạnh về các chương trình đòi hỏi giao diện khi thực thi cần can thiệp nhiều đến phần cứng, render… như game chẳng hạn, không phải tương thích trình duyệt.. Còn các ứng dụng web ngày nay với sự phát triển mạnh mẽ của HTML5, CSS3, các script, Ajax.. giao diện web cũng đang được “hiện đại hóa” rất nhiều, những ưu thế ngày càng được thể hiện trong ứng dụng web. Nhưng hầu như vẫn chưa có sự thống nhất, đồng bộ giữa 2 dạng ứng dụng này. Đến với WPF đã đưa ra giải pháp cho việc thống nhất giao diện của 2 dạng ứng dụng trên. Cả 2 sẽ được đồng nhất trong việc thiết kế ứng dụng trên windows, nghĩa là bạn chỉ cần thiết kế cho ứng dụng chạy trên windows và ứng dụng đó sẽ chạy được bình thường trên web mà ko cần làm gì thêm. 1.6. Tổng quan về Wpf Giống như các thành phần khác của DotNet Framework, WPF tổ chức các chức năng theo một nhóm namespace cùng trực thuộc namespace System.Windows. Bất kể chức năng nào được sử dụng, cấu trúc cơ bản của mọi ứng dụng WPF đều gần như nhau. Là ứng dụng Windows độc lập hay là một XBAP, một ứng dụng WPF điển hình bao giờ cũng gồm một tập các trang XAML và phần code tương ứng được viết bằng C# hoặc Visual Basic, còn gọi là các file code-behind. Tất cả các ứng dụng đều kế thừa từ lớp chuẩn Application của WPF. Lớp này cung cấp những dịch vụ chung cho mọi ứng dụng, chẳng hạn như các biến lưu trữ trạng thái của ứng dụng, các phương thức chuẩn để kích hoạt hay kết thúc ứng dụng. Mặc dù WPF cung cấp một nền tảng thống nhất để tạo giao diện người dùng, những công nghệ mà WPF chứa đựng có thể phân chia thành những thành
phần độc lập. Nhân của WPF là cơ chế tạo sinh đồ họa dựa trên vector và độc lập với độ phân giải nhằm tận dụng những lợi thế của phần cứng đồ họa hiện đại. WPF được mở rộng với các tập tính năng phát triển ứng dụng bao gồm 5
XAML, các control, cơ chế móc nối dữ liệu, layout, đồ họa 2 chiều, ba chiều, hoạt họa, style, khuôn dạng mẫu, văn bản, media, text và in ấn. WPF nằm trong .NET Framework, nên ngoài ra, ứng dụng WPF có thể kết hợp các thành phần khác có trong thư viện lớp của .NET Framework.
1.7. Layout và Control Để sắp đặt các thành phần khác nhau trên giao diện, ứng dụng WPF sử dụng panel. Mỗi panel có thể chứa các thành phần con, bao gồm các control như nút bấm hay hộp thoại, hay bản than những panel khác. Những loại panel khác nhau cho phép sắp xếp thành phần con theo những cách khác nhau. Ví dụ, DockPanel cho phép các thành phần con có thể được đặt dọc theo cạnh của panel đó, trong khi Grid cho phép sắp đặt các thành phần con của nó trên một lưới tọa độ. Giống như bất kỳ một công nghệ giao diện người dùng nào, WPF cung cấp một số lượng lớn các control. Ngoài ra, người dùng có thể tùy ý định nghĩa các control theo ý mình. Các control chuẩn gồm Button, Label, TextBox, ListBox, Menu, Slider, hay phức tạp hơn có SpellCheck, PasswordBox… Các sự kiện do người dùng tạo ra, như di chuyển chuột hay ấn phím, có thể được các control nắm bắt và xử lý. Trong khi các control và các thành phần giao diện khác có thể được đặc tả đầy đủ bằng XAML, các sự kiện bắt buộc phải được xử lý bằng mã trình.
6
1.8. Style và Template Giống như sử dụng Cascading Style Sheets (CSS) đối với HTML, việc định ra thuộc tính đồ họa cho các đối tượng giao diện một lần, rồi sau đó áp dụng lại cho các đối tượng khác cùng loại thường rất tiện lợi. WPF cũng cung cấp tính năng tương tự bằng việc sử dụng thành phần Style của XAML. Một Style có thể được dẫn xuất từ một Style khác, thừa kế hoặc chồng lên những thuộc tính đã thiết lập. Mỗi style có thể định nghĩa các trigger cho phép tạo ra những hiệu ứng tương tác đặc biệt, chẳng hạn như khi lướt chuột qua nút bấm, nút bấm chuyển thành màu vàng. WPF cũng hỗ trợ sử dụng template. Mỗi template tương tự như một style, và ở hai dạng: Template cho dữ liệu: sử dụng thành phần DataTemplate của XAML để thiết lập một nhóm thuộc tính hiển thị của dữ liệu như màu sắc, phương thức căn lề Template cho control: sử dụng thành phần ControlTemplate của XAML để định ra diện mạo của một control. 1.9. Text Giao diện người dùng ít nhiều đều hiển thị chữ hay text. Đối với phần lớn mọi người, đọc text trên màn hình thường khó hơn đọc trên giấy in. Đó là do chất lượng hiển thị text trên màn hình kém hơn so với khi in ra giấy. WPF tập
trung giải quyết vấn đề này, làm chất lượng text hiển thị trên màn hình tương đương trên giấy in. Cụ thể, WPF hỗ trợ các font chữ OpenType chuẩn, cho phép sử dụng các thư viện font đã có. WPF cũng hỗ trợ công nghệ font chữ mới ClearType, cho phép hiển thị các ký tự mịn hơn đối với mắt người, đặc biệt là trên màn hình tinh thể lỏng (LCD). Để nâng cao hơn nữa chất lượng hiển thị text, WPF cho phép một số công nghệ khác như chữ ghép, theo đó một nhóm ký tự được thay thế bằng một ảnh đơn nhất, tạo tâm lý thoải mái hơn khi đọc đối với người dùng. 1.10. Văn bản WPF hỗ trợ ba dạng văn bản: văn bản cố định (fixed), văn bản thích nghi (flow/adaptive) và văn bản XPS (XML Paper Specification). Kèm theo đó, WPF cũng cung cấp các dịch vụ để tạo, xem, quản lý, ghi chú, đóng gói và in ấn văn bản. Văn bản cố định trông không đổi bất kể chúng được hiển thị trên màn hình hay in ra máy in. Trong WPF, những văn bản dạng này được định nghĩa bằng phần tử FixedDocument trong XAML và được hiển thị bằng control DocumentViewer. Trong khi đó, văn bản thích nghi thường chỉ dùng để đọc trên màn hình, và có khả năng tự động thay đổi các thuộc tính hiển thị ảnh và 7
text cho phù hợp với kích thước cửa số hay các yếu tố môi trường khác nhằm
nâng cao chất lượng đọc cho người dùng. Văn bản thích nghi được định nghĩa bằng phần tử FlowDocument. Để hiển thị văn bản thích nghi, WPF sử dụng một số control khác nhau, chẳng hạn như FlowDocumentPageViewer, FlowDocumentScrollViewer, FlowDocumentReader… 1.11. Hình ảnh Control Image có thể hiển thị hình ảnh lưu trữ dưới nhiều khuôn dạng khác nhau, bao gồm JPEG, BMP, TIFF, GIF và PNG. Nó cũng có thể hiển thị hình ảnh dạng Windows Media Photo mới được sử dụng trong Windows Vista. Bất kể ở khuôn dạng nào, WPF sử dụng Windows Imaging Component (WIC) để tạo ra hình ảnh. Cùng với các codec dùng cho các khuôn dạng ảnh kể trên, WIC cũng cung cấp một nền tảng chung để bổ sung codec khác. 1.12. Video và Âm thanh Khi tốc độ của các bộ xử lý và truyền thông mạng ngày một nâng cao, video trở thành một phần tương tác lớn của người dùng với phần mềm. Người dùng cũng sử dụng nhiều thời gian để nghe nhạc và các dạng âm thanh khác trên máy tính. Do đó, WPF cung cấp tính năng hỗ trợ cả hai dạng media này thông qua phần tử MediaElement. Control này có thể chơi các định dạng video WMV, MPEG và AVI, và nhiều định dạng âm thanh khác nhau. 1.13. Đồ họa hai chiều Trong 20 năm gần đây, việc tạo ra đồ họa hai chiều trên Windows dựa trên Graphics Device Interface (GDI) và phiên bản sau của nó GDI+. Các ứng dụng Windows Forms phải sử dụng chức năng này thông qua một namespace khác hoàn toàn, bởi bản thân Windows Forms không tích hợp đồ họa 2 chiều. Đối với đồ họa 3 chiều thì càng tồi hơn, Windows Forms phải dựa trên công nghệ hoàn toàn biệt lập là Direct3D. Với WPF, vấn đề trở nên đơn giản hơn nhiều. Cả đồ họa 2 chiều và 3 chiều đều có thể được tạo ra trực tiếp trong XAML hoặc trong code sử dụng thư viện WPF tương ứng. Đối với đồ họa 2 chiều, WPF định ra nhóm control của các khuôn hình (shapes) mà ứng dụng có thể sử dụng để tạo nên hình ảnh, gồm: Line: Vẽ đường thẳng qua hai điểm.
Ellipse: Vẽ Ellipse Rectangle: Vẽ hình chữ nhật Polygon: Vẽ đa giác Polyline: Vẽ đa giác mở Path: Vẽ hình theo một đường bất kỳ 1.14. Đồ họa ba chiều WPF hỗ trợ đồ họa 3 chiều bằng việc gói các lời gọi API của Direct3D, và do vậy, việc sử dụng chúng trở nên thống nhất và đơn giản hơn đáng kể. Để hiển thị đồ họa ba chiều, ứng dụng WPF sử dụng control Viewport3D. Để tạo ra 8
các cảnh ba chiều, lập trình viên mô tả một hay nhiều mô hình, sau đó phân định cách thức các mô hình này được chiếu sáng hay hiển thị. Như thường lệ, điều này được thực hiện bằng XAML, bằng code hay trộn cả hai. Để mô tả mô hình, WPF cung cấp lớp GeometryModel3D để tạo ra hình dạng của mô hình. Khi mô hình đã được định hình, diện mạo bên ngoài của nó có thể được điều khiển bằng việc phủ lên các vật liệu (material). Chẳng hạn, lớp SpecularMaterial cho phép tạo bóng trên bề mặt mô hình. Bất kể được làm từ vật liệu gì, một mô hình có thể được chiếu sáng theo nhiều cách. Lớp DirectionalLight cho phép ánh sáng tới từ một hướng xác định, trong khi lớp AmbientLight tạo ra ánh sáng đồng đều trên mọi vật trong cảnh. Cuối cùng, để định ra cách nhìn cảnh, lập trình viên phải định ra một camera. Ví dụ, PerspectiveCamera cho phép phân định khoảng cách từ vị trí nhìn tới vật thể và kiểu nhìn phối cảnh (tuân theo luật gần xa). II.2. Kết hợp giữa WPF và Winform Thứ nhất, Windows Form là một công nghệ ra đời đã khá lâu và ổn định. Đa số các ứng dụng desktop hiện nay đều được xây dựng trên Windows Form. Trong khi đó, WPF chỉ mới xuất hiện được vài năm và nhiều lập trình viên vẫn quen thuộc với Windows Form hơn là WPF.
Thứ hai, WPF dù có nhiều ưu điểm nhưng vẫn chưa thực sự hoàn chỉnh. Một số tính năng của Windows Form (chẳng hạn một số loại control và hộp thoại) hiện vẫn chưa thể tìm thấy trong WPF. Trong những trường hợp đó, sử dụng lại các thành phần của Windows Form cho ứng dụng WPF (thay vì phát triển lại WPF control từ đầu) có thể sẽ là một tùy chọn đáng cân nhắc. Từ những lý do trên, có thể thấy rằng Windows Form sẽ chưa biến mất ngay. Thay vào đó, các ứng dụng Windows Form có sẵn sẽ được nâng cấp từ từ sang WPF. Điều này làm nảy sinh nhu cầu kết hợp WPF và Windows Form trong cùng một chương trình. Thật may, cả hai công nghệ này có thể sống chung một cách khá dễ dàng! Bài viết này sẽ trình bày một số phương pháp để giải quyết vấn đề trên: 1. Đặt các WPF control và Windows Form control trong các cửa sổ riêng: Đây là hướng tiếp cận đơn giản nhất, trong đó mỗi cửa sổ sẽ chỉ chứa một loại control (WPF control hoặc Windows Form control). Ta có thể thêm một cửa sổ Windows Form vào một ứng dụng WPF tương tự như đối với một ứng dụng Windows Form thông thường bằng cách click chuột phải vào tên project trong solution explorer, chọn Add -> New Item, sau đó chọn Windows Form trong Windows Form category, đặt tên và click Add. 9
Ngược lại, thêm một cửa sổ WPF vào một ứng dụng Windows Form hơi rắc rối hơn một chút vì Visual Studio không cung cấp tùy chọn này trong hộp thoại Add New Item. Tuy nhiên, ta có thể import một cửa sổ WPF có sẵn trong một project khác bằng cách chọn Add -> Existing Item và add cả hai file .xaml và .cs của cửa sổ đó. Với cách này, bạn sẽ phải tự add reference tới ba assembly sau: PresentationCore.dll, PresentationFramework.dll và WindowsBase.dll. Visual Studio sẽ cung cấp môi trường làm việc phù hợp (trình thiết kế, intellisense…) cho mỗi loại cửa sổ. Bạn có thể thiết kế và biên dịch chương
trình một cách tự nhiên như trong bất kì ứng dụng WPF hoặc Windows Form nào. Một lưu ý duy nhất là khi cần show một cửa sổ WPF ở dạng modeless từ trong một cửa sổ Windows Form (hoặc ngược lại), cần gọi phương thức EnableModelessKeyboardInterop (hoặc EnableWindowsFormInterop) để đảm bảo cửa sổ modeless có thể nhận keyboard input bình thường. Ví dụ trong trường hợp cửa sổ modeless WPF: MyWindow window = new MyWindow(); ElementHost.EnableModelessKeyboardInterop(window); window.Show(); Bạn có thể sẽ cần add reference đến assembly WindowsFormIntegration.dll để sử dụng lớp ElementHost. 2. Đặt WPF control vào cửa sổ Windows Form: Trong nhiều trường hợp chúng ta buộc phải sử dụng các WPF control và Windows Form control trong cùng một cửa sổ. Lớp ElementHost cho phép đặt các WPF control trong cửa sổ Windows Form. Chỉ cần tạo WPF control mong muốn và đặt nó vào trong ElementHost, sau đó thêm ElementHost vào tập các control của form. ElementHost host = new ElementHost(); System.Windows.Controls.DatePicker wpfDatePicker = newSystem.Windows.Controls.DatePicker(); host.Dock = DockStyle.Fill; host.Child = wpfDatePicker; this.Controls.Add(host);
10
3. Đặt Windows Form control vào cửa sổ WPF: WPF cung cấp lớp WindowsFormHost có thể chứa một Windows Form control trong property Child. Ta có thể sử dụng lớp này theo kiểu khai báo
trong XAML hoặc bằng lập trình: <Grid> <WindowsFormsHost> <wf:TextBox x:Name="txtWinForm"/> </WindowsFormsHost> </Grid> để sử dụng được tag <WindowsFormHost> như trên cần thêm dòng khai báo sau vào tag <Window>: xmlns:wf="clrnamespace:System.Windows.Forms;assembly=System.Windows.Forms" Còn đây là đoạn code để thêm Windows Form control vào cửa sổ WPF bằng C#: System.Windows.Forms.Integration.WindowsFormsHost host = newSystem.Windows.Forms.Integration.WindowsFormsHost(); // Create the ListBox control. System.Windows.Forms.ListBox lstBox = new System.Windows.Forms.ListBox(); lstBox.Items.Add("Item 1"); lstBox.Items.Add("Item 2"); // Assign the ListBox control as the host control's child. host.Child = lstBox; // Add the interop host control to the Grid this.MyGrid.Children.Add(host); Nhớ rằng bạn cần Add Reference tới assembly System.Windows.Form và WindowsFormIntegration để đoạn code trên hoạt động. 4. Một vài hạn chế khi sử dụng WPF control và Windows Form control trong cùng một cửa sổ: 1. Trong nhiều trường hợp, các control của Windows Form không thể thay đổi kích thước hoặc chỉ có thể thay đổi theo một chiều nhất định. 2. Các control của Windows Form cũng không thể được xoay hoặc làm nghiêng. Nếu bị áp dụng các hiệu ứng này, WindowsFormHost sẽ phát
11
sinh sự kiện LayoutError, và cuối cùng sẽ gây InvalidOperationException nếu không được xử lý. II.3 Ngôn ngữ WPF 3.1. Khởi tạo project mới Để khởi tạo Project mới bạn vào menu: File -> New -> New Projecjt hoặc cũng có thể dùng phím tắt Ctrl + Shift + N. Sau đó sẽ xuất hiện hộp thoại bên dưới. Tại List bên trái ta chọn ngôn ngữ C# -> Ứng dụng Windows. Trong list ở giữa ta chọn WPF Application để khởi tạo 1 project WPF mới. Bạn có thể đổi tên và thư mục lưu trữ cho project tại Name và Location bên dưới. Sau đó OK để bắt đầu.
Bước tiếp theo sẽ xuất hiện giao diện như hình bên dưới. Ta thấy có một đối tượng MainWindow giữa màn hình, đây là Form chính trong chương trình chúng ta. Như ta thấy dạng form này không có boder giống như dạng Form 12
thông thường trong ứng dụng C# Winform Application. Việc lược bỏ boder cho thấy được rằng ứng dụng này hướng tới cả môi trường web, nếu bạn thực thi ứng dụng thì không cần đến phần boder và ngoài việc loại bỏ boder cũng đem lại sự đơn giản hơn cho ứng dụng trên nền windows vì thực tế ta hầu như cũng không thao tác được gì trên boder này. Một điểm khác nữa là form luôn được căn chỉnh giữa màn hình thay vì nằm góc trên bên trái như ứng dụng Winform thông thường. 3.2. Hộp thoại, những công cụ ta cần quan tâm đầu tiên: Toobox: Nơi chưa các control cho ứng dụng của bạn. Các control cũng tương tự như ứng dụng winform, ngoài ra còn được bổ sung một số control mới với những tính năng hay hơn,
khả năng tùy biến cao hơn. Chúng ta sẽ lần lượt tìm hiểu trong các lượt bài sau này. Properties: Nơi thiết lập các thuộc tính cho control, thay đổi kích thước hình dạng, màu sắc… và thiết lập các event cho controls. Solution Eplorer: Tại đây ta sẽ thấy được các thành phần, tài nguyên bên trong của project. Một điểm mới thú vị của WPF là thanh trượt để zoom form lên kích thước lớn hơn, điều này giúp ta dễ dàng zoom lớn lên nhằm bố trí các control chính xác hơn, trường hợp kích thước form quá lớn ta có thể thu nhỏ để nhìn toàn thể form được bao quát hơn. Bên dưới cho phép ta thay đổi giữa 2 chế độ làm việc: design – viết mã XAML. Hoặc nếu trường hợp màn hình của bạn đủ lớn có thể chọn chế độ hiển thị cả 2 khung làm việc đồng thời.
13
Bên dưới là hình ảnh chi tiết của 3 Box công cụ: ToolBox, Solution Explorer và Properties.
14
3.3. Bắt đầu project đầu tiên: Cũng như trong ứng dụng Winform bạn có thể thêm các control trực tiếp từ Toolbox thông qua các thao tác kéo thả. Ngoài ra bạn có thêm thêm control bằng cách viết mã trong XAML. Đây là điểm mới và cũng là thế mạnh trong WPF. Bạn có thể nhanh chóng tạo 1 control và thiết lập các thuộc tính một cách nhanh chóng bằng một số đoạn code ngắn gọn. Trong ví dụ bên dưới chúng ta tạo 1 button và 1 comboBox nằm trong button. Điều này khá lạ phải không? Trong ứng dụng Winform không cho phép tạo control lồng nhau như vậy, nhưng trong WPF bạn hoàn toàn có thể, không chỉ
thế mà còn rất nhiều điều thú vị đang chờ bạn khám phá.
15
Biên dịch và chạy ứng dụng.
3.4 Giới thiệu về XAML 16
XAML được dùng để tạo giao diện đồ họa cho ứng dụng thông qua các đối tượng của .Net hoặc do bạn tự định nghĩa. Do đó mỗi thẻ XAML phải ánh xạ và có tên tương ứng với một lớp. Giống như các ngôn ngữ đánh dấu HTML, XML cho phép các thẻ lồng nhau. Điều này giúp bạn tạo ra các control đa dạng hơn, ví dụ như bạn có thể lồng một TextBox vào trong Button. Bên cạnh đó, các giá trị có kiểu dữ liệu cơ bản như chuỗi, số, màu,… mà bạn gán cho các thuộc tính của thẻ cũng phải được đặt trong cặp nháy kép. Ví dụ với đoạn XAML đơn giản sau (MainWindow.xaml). Listing 1: 1 2 xmlns=" />3 xmlns:x=" />4 Title="Hello XAML" Height="250" Width="250"> 5 <Button> 6 <TextBox>I'm a TextBox</TextBox>
7 </Button> 8 </Window> Sẽ tạo cho ta một giao diện cửa sổ với tiêu đề là “Hello XAML” :
17
Thay vì sử dụng XAML, bạn có thể dùng mã lệnh code-behind để thay thế. Để minh họa, bạn hãy tạo một C# Empty Project, sau đó Add reference các thư viện .Net cần thiết: PresentationCore -
PresentationFramework
-
WindowsBase
-
System.Xaml
Tạo một class mới có nội dung sau: 18
Listing 2: 1
using System; 2 using System.Windows; 3 using System.Windows.Controls; 4 5 namespace Y2WpfExample 6 { 7 class Program 8 { 9 [STAThread] 10 static void Main() 11 { 12 Button button = new Button() 13 { 14 Content = new TextBox() 15 { 16 Text = "I'm a TextBox",
Ví dụ trên sử dụng cách khởi tạo nhanh đối tượng của C# 3. Nếu thấy khó hiểu, bạn có thể viết theo cách thông thường như: Button button = new Button(); TextBox txt = new TextBox(); txt.Text = “I’m a TextBox”; 19
button.Content = txt; Giao diện chương trình khi thực thi sẽ giống với ví dụ mà ta viết bằng XAML trước đó kèm theo một cửa sổ console (bạn có thể vào Project > Project Properties để chuyển Output typethành Windows Application). Namespace trong XAML Namespace mặc định Các namespace trong XAML được khai báo qua thuộc tính (attribute) xmlns (XML name space). Thuộc tính xmlns này cho phép sử dụng nhiều lần trong tài liệu XAML, tuy nhiên mỗi thuộc tính này được phân biệt thông qua prefix mà bạn gán cho namespace mà nó khai báo. Namespace chứa các lớp mà bạn cần dùng đến trong ứng dụng. Ngoài namespace mặc định dùng cho những lớp cơ bản của WPF, bạn có thể thêm bất kì namespace nào khác bên trong hoặc ngoài assembly. Hãy xem lại ví dụ trước: 1 2 xmlns=" />3 xmlns:x=" />4 Title="Hello XAML" Height="250" Width="250"> 5 <Button> 6
<TextBox>I'm a TextBox</TextBox> 7 </Button> 8 </Window> Các thuộc tính xmlns khai báo hai namespace được sử dụng trong các ứng dụng WPF: xmlns=” />xmlns:x=” />Namespace đầu tiên ” chứa các lớp cơ bản được sử dụng trong WPF. Namespace được khai báo không kèm theo prefix và là namespace mặc định đối với tất cả các lớp mà bạn sử dụng trong tập tin XAML hiện tại. • Namespace thứ hai “ />chứa các chức năng của XAML để bổ sung thuộc tính cho các đối tượng và chỉ ra cách bộ phân tích XAMLsẽ xử lý. Namespace này được ánh xạ vào prefix ‘x’ như một bí danh (alias), trong ví dụ bạn cũng có thể thấy cách prefix được sử dụng: x:Class=”WpfApplication1.MainWindow” •
20
Việc sử dụng bí danh này cũng tương tự như trong C#: using Text = System.Text; Những chức năng của namespace gán cho prefix x, bạn có thể tham khảo tại địa chỉ sau: XAML Namespace (x:) Language Features Bao gồm các phần để bạn có thể tham khảo nhanh: x:Array Markup Extension x:Class Directive x:ClassModifier Directive
x:Code Intrinsic XAML Type x:FieldModifier Directive x:Key Directive x:Member Directive x:Members Directive x:Name Directive x:Null Markup Extension x:Shared Attribute x:Property Directive x:Static Markup Extension x:Subclass Directive x:Type Markup Extension x:TypeArguments Directive x:Uid Directive x:XData Intrinsic XAML Type XamlName Grammar {} Escape Sequence / Markup Extension xml:lang Handling in XAML xml:space Handling in XAML Bạn có thể thắc mắc là việc đặt hai namespace trên giống theo dạng địa chỉ URL có tác dụng gì? Một điều chắc chắn rằng các lớp, chức năng trong hai namespace mà ta sử dụng đều nằm trong máy cục bộ. Namespace dạng URL này chỉ là một định danh và giúp gom tất cả các namespace cần thiết vào trong một namespace duy nhất. Thêm namespace vào tài liệu XAML 21
Để thêm các namespace khác vào tài liệu XAML, bạn cũng sử dụng thuộc tính xmlns kèm theo tên một prefix tự đặt. Trình soạn thảo của Visual Studio
tự động xổ ra các namespace có hiệu lực, bao gồm các namespace do bạn tạo ra. Tên của các namespace này được khai báo bắt đầu bằng chuỗi prefix “clrnamespace”. Nếu namespace không nằm trong assembly hiện tại, bạn phải chỉ ra tên của assembly chứa nó trong tên của namespace. Ví dụ sau khai báo một namespace Microsoft.Win32 trong assembly mscorlib với alias là win32: xmlns:win32=”clr-namespace:Microsoft.Win32;assembly=mscorlib” Thuộc tính xmlns có thể được override bằng cách khai báo với alias trùng tên với alias của phần tử cha trong tài liệu XAML. Ra ngoài phạm vi này, prefix sẽ được trả lại để ánh xạ cho namespace ban đầu. Phần tử gốc của tài liệu XAML Khi bạn tạo ra các đối tượng top-level (phần tử gốc) trong một tài liệu XAML. Chẳng hạn như Application, Window, Page hoặc subclass của các element tự tạo khác. Bạn không thể sử dụng tên mới của subclass này MainWindow để khai báo và tạo thể hiện của nó bởi vì namespace cần thiết chưa được khai báo. Điều này là dĩ nhiên bởi vì namespace được khai báo bằng attribute bên trong đối tượng. Giải quyết cho vấn đề này, XAML sử dụng thuộc tính Class trong namespace “ (được gán cho x) để xác định lớp sẽ được tạo thể hiện thay cho lớp được dùng để khai báo. … </Window> Như bạn thấy trong ví dụ tập tin MainWindow.xaml, mặc dù thẻ Window được sử dụng để khai báo là thành phần top-level, nhưng thực tế một thể hiện của lớp MainWindow sẽ được tạo ra. Tất nhiên lớp MainWindow phải được kế thừa từ Window. Điều này giống như việc bạn tạo một subclass của lớp Window trong code-behind. Và như bạn có thể suy luận, thuộc tính x:Class này chỉ hỗ trợ cho phần tử toplevel trong một tài liệu XAML.
22
Một ví dụ khác cho ra cùng kết quả như ví dụ ở Listing 1 và Listing 2. Ta tách riêng lớp Button ra để tạo một tài liệu XAML mới, lúc này lớp Button trở thành phần tử top-level. Bạn nhấn phải chuột vào project để add một User Control và đặt tên là Y2Button. Chỉnh sửa tập tin Y2Button.xaml như nội dung sau và sửa lại lớp thừa kế là Button trong tập tin code-behind Y2Button.xaml.cs:
6 <y2:Y2Button /> 7 8 </Window> Property, Event và Attribute Các property, event của những đối tượng có thể được xem như những attribute trong các thẻ của XAML. Đối với các property có kiểu đơn giản, bạn có thể gán trực tiếp bằng cách dùng attribute với giá trị nằm trong cặp nháy kép. Như bạn thấy trong các đoạn mã ở các phần trên của đối tượng Window: Title=”Hello XAML” Height=”250″ Width=”250″ Với các property phức tạp bạn cần phải sử dụng các thẻ để định nghĩa, các thẻ này phải nằm bên trong thẻ khai bảo property của đối tượng. Ví sau 23
minh họa cách tô màu nền gradient cho Window bằng cách đặt thuộc tính Background của Window với một LinearGradientBrush. LinearGradientBrush lại chứa property GradientStops là một collection các điểm dừng để xác định màu. 1 2 xmlns=" />3 xmlns:x=" />4 xmlns:y2="clr-namespace:WpfApplication1" 5 Title="Hello XAML" Height="250" Width="250"> 6 <Window.Background>
5 linearBrush.GradientStops.Add(new GradientStop(Colors.LightCyan, 0.4)); 6 linearBrush.GradientStops.Add(new GradientStop(Colors.LightBlue, 0.7)); 7 linearBrush.GradientStops.Add(new GradientStop(Colors.Blue, 1)); 8 this.Background = linearBrush; 9 // [...] Và cho ra kết quả:
24
Với event, bạn đặt tương tự như các property đơn giản, gán giá trị cho tên event với tên của phương thức xử lý tương ứng. <Button Click=”Button_Click”>Click Me!</Button> II.4. GIỚI THIỆU SQL SERVER
SQL là một hệ thống quản trị CSDLQH (RDBMS) nhiều người dùng kiểu