Đây là bài viết thứ hai trong loạt bài viết hướng dẫn Lập trình Windows 10.
Ứng dụng Windows 10 hay còn có tên gọi kỹ thuật là ứng dụng Universal Windows Platform hay ứng dụng UWP có khả năng chạy được trên rất nhiều thiết bị chạy hệ điều hành Windows 10 như máy tính PC, laptop, điện thoại di động, TV, … Với khả năng này, khi phát triển ứng dụng UWP, bạn chỉ cần build ra một package và package đấy có thể chạy được trên tất cả các thiết bị nói trên. Tuy nhiên, việc chạy được là một chuyện, làm sao để tối ưu trải nghiệm người dùng (UX) trên các thiết bị nói trên lại là một bài toán tương đối đau đầu đối với các lập trình viên.

Để giải quyết vấn đề trên, trong bài viết này, mình và các bạn sẽ cùng nhau tìm hiểu một số kiến thức liên quan đến kích thước màn hình, những điều cần lưu ý khi thiết kế giao diện cho ứng dụng Windows 10. Bài viết sẽ được chia thành hai phần, phần một mình sẽ nói sâu về hướng màn hình (screen orientation), làm sao có thể xác định được hướng màn hình hiện tại cũng như làm sao có thể biết được khi nào thì hướng màn hình thay đổi. Phần hai mình sẽ nói sâu về kỹ thuật thiết kế responsive trong Windows 10 sử dụng AdativeTrigger và RelativePanel hoàn toàn mới.
Hướng màn hình
Quan tâm đến hướng màn hình là một trong những công việc mà bạn cần phải làm khi thiết kế giao diện ứng dụng, làm sao khi người dùng đặt máy tính nằm ngang sang nằm dọc ứng dụng của bạn vẫn hiển thị đầy đủ thông tin cũng như các thành phần giao diện vẫn được bố trí phù hợp sao cho người dùng có thể dễ dùng nhất với kích thước hẹp của màn hình.
Hiện tại Windows 10 hỗ trợ 4 hướng màn hình:
- Hướng màn hình nằm ngang (Landscape)
- Hướng màn hình nằm ngang nhưng lật ngược (Landscape-flipped)
- Hướng màn hình nằm dọc (Portrait)
- Hướng màn hình nằm dọc nhưng lật ngược (Portrait-flipped)
Mặc định ứng dụng Windows 10 hỗ trợ cả 4 hướng màn hình, tuy nhiên bạn có thể thiết lập giới hạn chỉ một số hướng màn hình được ứng dụng hỗ trợ bằng cách mở file Package.appxmanifest > vào thẻ Application > ở mục Supported rotations, tích vào ô trống tương ứng với hướng màn hình mà ứng dụng hỗ trợ.
Để xác định được hướng màn hình hiện tại, Windows 10 có cung cấp cho chúng ta một lớp (class) có tên DisplayInformation nằm trong namespace Windows.Graphics.Display. Các bạn chỉ cần gọi đến thuộc tính CurrentOrientation để biết được hướng hiện tại của màn hình là gì.
Để tạo mới một thể hiện (instance) của lớp DisplayInformation, các bạn không tạo thông qua hàm khởi tạo (constructor) mà các bạn sẽ gọi hàm static GetForCurrentView của lớp DisplayInformation.
Windows.Graphics.Display.DisplayInformation displayInformation = Windows.Graphics.Display.DisplayInformation.GetForCurrentView();
Và gọi đến thuộc tính CurrentOrientation để biết được hướng hiện tại của màn hình là gì:
Windows.Graphics.Display.DisplayInformation displayInformation = Windows.Graphics.Display.DisplayInformation.GetForCurrentView(); if (displayInformation.CurrentOrientation == Windows.Graphics.Display.DisplayOrientations.Landscape || displayInformation.CurrentOrientation == Windows.Graphics.Display.DisplayOrientations.LandscapeFlipped) { // Hướng màn hình nằm ngang } else if (displayInformation.CurrentOrientation == Windows.Graphics.Display.DisplayOrientations.Portrait || displayInformation.CurrentOrientation == Windows.Graphics.Display.DisplayOrientations.PortraitFlipped) { // Hướng màn hình nằm dọc } else { // Hướng màn hình không xác định }
Để biết được khi nào thì hướng màn hình thay đổi, các bạn chỉ cần xử lý sự kiện OrientationChanged trong lớp DisplayInformation.
Windows.Graphics.Display.DisplayInformation displayInformation = Windows.Graphics.Display.DisplayInformation.GetForCurrentView(); displayInformation.OrientationChanged += DisplayInformationOnOrientationChanged;
Kỹ thuật thiết kế Responsive
Với việc cung cấp trigger mới là AdaptiveTrigger và control mới là RelativePanel, việc áp dụng kỹ thuật thiết kế responsive vào ứng dụng Windows 10 là khá đơn giản.
AdaptiveTrigger cho phép bạn đặt ra một khoảng kích thước nhất định và đưa ra các xứ lý khi mà kích thước màn hình lọt vào khoảng kích thước mà bạn thiết lập.
Còn RelativePanel, đây là một panel hoàn toàn mới trong Windows 10, cho phép bạn đặt các phần tử bên trong panel với vị trí tương đối, có liên quan tới nhau. Ví dụ bạn có thể đặt 2 TextBox bao gồm TextBox A và TextBox B trong 1 RelativePanel và thiết lập vị trí của TextBox A luôn luôn nằm ở rìa bên phải của RelativePanel và vị trí của TextBox B luôn luôn nằm dưới TextBox A chẳng bạn. Chi tiết về RelativePanel sẽ được mình nói ở trong bài viết tới.
Dưới đây là một ví dụ cụ thể của việc áp dụng AdaptiveTrigger và RelativePanel vào trong thiết kế giao diện Windows 10:
Mình đặt ra một bài toán là mình có 1 Page gồm có 2 hình vuông, một hình có màu nâu và một hình có màu xanh dương. Khi màn hình có kích thước chiều rộng lớn hơn 720 px thì 2 hình vuông này sẽ nằm song song nhau trên một phương ngang. Còn khi màn hình có kích thước chiều rộng nhỏ hơn 720 px thì 2 hình vuông này sẽ nằm trên 1 chiều dọc và hình vuông màu nâu nằm trên hình vuông màu xanh dương.
Để giải quyết bài toán trên, trước hết mình sẽ tạo 2 Border (Border01 và Border02) có kích thước giống nhau là 250×250 px. Border01 có Background là Brown và Border02 có Background là Blue. 2 Border này mình sẽ đặt trong 1 thẻ RelativePanel.
<RelativePanel> <Border x:Name="Border01" Background="Brown" Width="250" Height="250" /> <Border x:Name="Border02" Background="Blue" Width="250" Height="250" /> </RelativePanel>
Để bắt được sự kiện khi kích thước chiều rộng của màn hình lớn hơn 720 px, mình sẽ tạo mới một thẻ VisualState trong VisualStateGroup rồi sau đó trong VisualState.StateTriggers, mình sẽ tạo mới một thẻ AdaptiveTrigger với thuộc tính MinWindowWidth bằng 720.
<VisualStateManager.VisualStateGroups> <VisualStateGroup> <!-- Kích thước màn hình >= 720 --> <VisualState> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>
Sau đó, để cho Border01 và Border02 nằm song song nhau trên một phương ngang, mình sẽ thiết lập thuộc tính RelativePanel.RightOf của Border02 với giá trị bằng Border01 trong thẻ Setter của VisualState.Setters.
<VisualStateManager.VisualStateGroups> <VisualStateGroup> <!-- Kích thước màn hình >= 720 --> <VisualState> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="Border02.(RelativePanel.RightOf)" Value="Border01" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>
Còn với trường hợp kích thước chiều rộng của màn hình nhỏ hơn 720 px, mình sẽ tạo mới một thẻ VisualState khác và trong VisualState.StateTriggers, mình tạo mới một thẻ AdaptiveTrigger với thuộc tính MinWindowWidth bằng 0. Sau đó, mình sẽ thiết lập thuộc tính RelativePanel.Below của Border02 với giá trị bằng Border01 trong thẻ Setter của VisualState.Setters để cho Border01 và Border02 nằm trên 1 chiều dọc và Border01 nằm trên Border02.
<VisualStateManager.VisualStateGroups> <VisualStateGroup> <!-- Kích thước màn hình >= 720 --> <VisualState> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="Border02.(RelativePanel.RightOf)" Value="Border01" /> </VisualState.Setters> </VisualState> <!-- Kích thước màn hình < 720 và >= 0 --> <VisualState> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0"></AdaptiveTrigger> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="Border02.(RelativePanel.Below)" Value="Border01" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>
Tổng kết
Như vậy là mình và các bạn đã cùng nhau tìm hiểu kỹ thuật làm sao có thể xác định được hướng màn hình hiện tại, xác định được khi nào hướng màn hình thay đổi cũng như một số kỹ thuật thiết kế responsive sử dụng AdaptiveTrigger và RelativePanel trong Windows 10.
Các bạn có thể tải source code của project mà mình sử dụng để viết bài này tại đây.
Ở bài viết tiếp theo, mình và các bạn sẽ cùng khám phá một số control mới trong Windows 10.
Trả lời