Layout trong WPF

Layout trong WPF

Trong bài ví dụ đơn giản của phần 1 – mở đầu.  mình có đề cập đến khái niệm Grid. Grid chính là 1 dạng Panel và WPF sử dụng các dạng panel khác nhau để bố trí các phần tử trên giao diện người dùng.

Trước đây, Khi lập trình VB Form, Access Form,… ta phải tuân theo nguyên tắc bố trí tuyệt đối. Tức là việc sắp xếp các Control phải luôn dựa vào tọa độ điểm ảnh cố định. Khi thay đổi kích thước Form, các Control như Label, Button vẫn sẽ không tự động kéo giãn để phù hợp với kích thước Form có thể làm nội dung bị che đi hoặc không cân đối. Điều này đã tạo khó khăn cho người lập trình. Trong khi ứng dụng web lại có 1 ưu thế là các phần tử như <div> , <table> cho phép co dãn tự động. Sau đó Windows forms đưa ra khái niệm Dock và Anchor đã bổ sung cách bố trí linh hoạt hơn. Và WPF tiếp bước xu hướng này với việc bố trí giao diện dựa trên Panel.

Các dạng Panel thông dụng với mỗi đặc trưng riêng: StackPanel, WrapPanel, DockPanel, Canvas, Grid.

1.      Lưu ý nhỏ về Panel:

Chúng ta trở lại đoạn XAML  rỗng sau khi tạo mới 1 ứng dụng WPF:

<Window x:Class=”WpfApplication2.Window1″

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

    Title=”Window1″ Height=”300″ Width=”300″>

    <Grid>

    </Grid>

</Window>

Ta có thể thấy môi trường tạo sẵn cho ta 1 cặp thẻ Grid trong cặp thẻ Window. Điều gì sẽ xảy ra khi ta xóa Grid đi.

clip_image002

Không báo lỗi. Và bây giờ ta thử tạo 1 Button xem. Ta tạo bằng cách đơn giản nhất là kéo thả trên thanh Toolbox. Lúc này ta gặp khó khăn là không thể di chuyển đến vị trí khác dễ dàng bằng cách nắm kéo nữa mà phải hiệu chỉnh thuộc tínhMargin.

. clip_image004

Mặt khác sau khi tạo 1 control, ta lại không thể tạo thêm 1 control khác nữa.

Đó là vì phần lớn các phần tử trong ứng dụng WPF (window, button,…) chỉ có thể chứa duy nhất 1 phần tử con. Trong ví dụ, Window đã chứa 1 button nên không thể chứa tiếp phần tử khác. Để giải quyết vấn đề này, ta chỉ việc bỏ 1 dạng panel (ví dụ như Grid) vào trong Window rồi mới bỏ các button vào trong panel đó.

2.      StackPanel

Đúng với tên gọi của nó, Panel này cung cấp 1 cách bố trí như ngăn xếp.

Code XAML:

<Window x:Class=”WpfApplication2.Window1″

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

    Title=”Window1″ Height=”300″ Width=”300″>

    <StackPanel>

        <Button>Nút 1</Button>

        <Button>Nút 2</Button>

        <Button>Nút 3</Button>

    </StackPanel>

</Window>

Giao diện sẽ là:

clip_image006clip_image007

Mặc định của StackPanel là sẽ bố trí theo phần tử theo chiều dọc (Vertical) như hình trên. Lúc này các phần tử sẽ bám vào cạnh left, top, right. Khi thay đổi kích thước Form, ta sẽ thấy rõ:

clip_image008

clip_image009

Tương tự StackPanel cũng có thể bố trí theo chiều ngang bằng cách thay đổi thuộc tính Orientation

Code XAML:

    <StackPanel Orientation=”Horizontal”>

        <Button>Nút 1</Button>

        <Button>Nút 2</Button>

        <Button>Nút 3</Button>

    </StackPanel>

clip_image011

3.      WrapPanel

Mặc định là sẽ xếp phần tử từ trái sang phải. Hết không gian thì sẽ xuống dòng

    <WrapPanel>

        <Button>Nút 1</Button>

        <Button>Nút 2</Button>

        <Button>Nút 3</Button>

        <Button>Nút 4</Button>

    </WrapPanel>

clip_image012                                          clip_image013

4.      DockPanel

Bản chất của DockPanel là bám. Vì vậy có thể xác định cạnh mà phần tử muốn bám (Left, Top, Right, Bottom) thông qua thuộc tính DockPanel.Dock như ví dụ sau:

    <DockPanel>

        <Button DockPanel.Dock=”Left”>Nút 1</Button>

        <Button DockPanel.Dock=”Top”>Nút 2</Button>

        <Button DockPanel.Dock=”Right”>Nút 3</Button>

        <Button DockPanel.Dock=”Bottom”>Nút 4</Button>

        <Button>Nút 5</Button>

    </DockPanel>

clip_image014

Nếu phần tử không có xác định DockPanel.Dock thì sẽ mặc định chiếm phần không gian còn lại của DockPanel.

5.      Canvas

Đặc điểm của Canvas là sắp xếp các phần tử theo tọa độ rõ ràng: cách lề trái bao nhiêu, lề trên bao nhiêu… (giống giống anchor) thông qua các thuộc tính Canvas.Left, Canvas.Right, Canvas.Top, Canvas.Bottom.

    <Canvas>

        <Button Canvas.Left=”50″>Nút 1</Button>

        <Button Canvas.Bottom=”50″>Nút 2</Button>

        <Button Canvas.Right=”50″>Nút 3</Button>

        <Button Canvas.Top=”50″>Nút 4</Button>

        <Button Canvas.Left=”22″>Nút 5</Button>

    </Canvas>

clip_image015

 

Button Nút 5 được khai báo sau Button Nút 1 nên sẽ đè lên Nút 1. Đây chính là khái niệm Z-Order. Tuy vậy, chúng ta cũng có thể thay đổi bằng cách chỉnh thuộc tính Canvas.ZIndex của từng phần tử. Phần tử nào có ZIndex càng lớn thì nó sẽ càng nằm phía trước. Ví dụ như ta muốn Button Nút 1 nằm phía trước Button Nút 5, ta có:

    <Canvas>

        <Button Canvas.Left=”50″ Canvas.ZIndex=”2″>Nút 1</Button>

        <Button Canvas.Bottom=”50″>Nút 2</Button>

        <Button Canvas.Right=”50″>Nút 3</Button>

        <Button Canvas.Top=”50″>Nút 4</Button>

        <Button Canvas.Left=”22″ Canvas.ZIndex=”1″>Nút 5</Button>

    </Canvas>

Số 2 và 1 ở đây chỉ minh họa, miễn sao ZIndex của Nút 1 lớn hơn ZIndex của Nút 5 là ok.

 

 

 

One response to “Layout trong WPF

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất /  Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )

Connecting to %s