WPF cung cấp nhiều container để sắp xếp các thành phần giao diện. Dưới đây là các loại container phổ biến nhất:
1. StackPanel
Container này xếp các phần tử theo hướng dọc hoặc ngang. Mỗi phần tử chiếm toàn bộ chiều rộng (nếu dọc) hoặc chiều cao (nếu ngang) của container.
Thuộc tính Orientation quyết định hướng sắp xếp:
- Vertical (mặc định): Xếp từ trên xuống dưới
- Horizontal: Xếp từ trái sang phải
Ví dụ sắp xếp theo chiều dọc:
<Window
x:Class="DemoLayout.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="StackPanel Demo"
Width="600"
Height="400">
<StackPanel Padding="10">
<TextBox x:Name="txtInput" Margin="0,0,0,8" Height="30"/>
<Button x:Name="btnSubmit" Content="Gửi" Margin="0,0,0,8" Height="35"/>
<Button x:Name="btnCancel" Content="Hủy" Margin="0,0,0,8" Height="35"/>
<Button x:Name="btnReset" Content="Đặt lại" Height="35"/>
</StackPanel>
</Window>
Để chuyển sang sắp xếp ngang, thêm thuộc tính sau:
<StackPanel Padding="10" Orientation="Horizontal">
2. WrapPanel
Container tự động xuống dòng khi không còn đủ không gian. Phù hợp cho danh sách các nút hoặc hình ảnh có kích thước đồng nhất.
<Window
x:Class="DemoLayout.WrapDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WrapPanel Demo"
Width="450"
Height="300">
<WrapPanel ItemWidth="100" ItemHeight="40" Margin="8">
<Button Content="A" Margin="4"/>
<Button Content="B" Margin="4"/>
<Button Content="C" Margin="4"/>
<Button Content="D" Margin="4"/>
<Button Content="E" Margin="4"/>
<Button Content="F" Margin="4"/>
<Button Content="G" Margin="4"/>
<Button Content="H" Margin="4"/>
</WrapPanel>
</Window>
Thuộc tính quan trọng:
ItemWidth/ItemHeight: Kích thước đồng nhất cho tất cả phần tửOrientation: Horizontal (mặc định) hoặc Vertical
3. DockPanel
Container cho phép neo các phần tử vào các cạnh (trái, phải, trên, dưới). Phần tử cuối cùng tự động chiếm không gian còn lại.
<Window
x:Class="DemoLayout.DockDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DockPanel Demo"
Width="700"
Height="500">
<DockPanel LastChildFill="True">
<Menu DockPanel.Dock="Top" Height="25">
<MenuItem Header="Tệp"/>
<MenuItem Header="Chỉnh sửa"/>
</Menu>
<StatusBar DockPanel.Dock="Bottom" Height="25">
<TextBlock Text="Sẵn sàng"/>
</StatusBar>
<StackPanel DockPanel.Dock="Left" Width="150" Background="#EEE">
<Button Content="Mục 1" Margin="5"/>
<Button Content="Mục 2" Margin="5"/>
</StackPanel>
<TextBox Text="Nội dung chính" AcceptsReturn="True"/>
</DockPanel>
</Window>
Lưu ý: Thuộc tính LastChildFill mặc định là True, phần tử cuối sẽ lấp đầy khoảng trống.
4. Grid
Container linh hoạt nhất, chia giao diện thành các hàng và cột. Đây là container được sử dụng phổ biến nhất trong WPF.
<Window
x:Class="DemoLayout.GridDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Grid Demo"
Width="500"
Height="350">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Tên:" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Height="25" Margin="5"/>
<Label Grid.Row="1" Grid.Column="0" Content="Mô tả:" VerticalAlignment="Top"/>
<TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
AcceptsReturn="True" TextWrapping="Wrap" Margin="5"/>
<Button Grid.Row="2" Grid.Column="1" Content="Lưu" Width="80"
HorizontalAlignment="Right" Margin="5"/>
<Button Grid.Row="2" Grid.Column="2" Content="Đóng" Width="80" Margin="5"/>
</Grid>
</Window>
Cách định nghĩa kích thước:
| Cú pháp | Ý nghĩa |
|---|---|
200 | Giá trị cố định 200 pixel |
Auto | Tự động theo nội dung |
* | Chia phần còn lại theo tỷ lệ |
2* | Gấp đôi phần của * |
5. Canvas
Container đơn giản nhất, định vị tuyệt đối các phần tử bằng tọa độ. Phù hợp cho đồ họa, sơ đồ hoặc giao diện tùy chỉnh.
<Window
x:Class="DemoLayout.CanvasDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Canvas Demo"
Width="600"
Height="400">
<Canvas Background="WhiteSmoke">
<Rectangle Canvas.Left="50" Canvas.Top="30"
Width="120" Height="80" Fill="SteelBlue"/>
<Ellipse Canvas.Left="200" Canvas.Top="50"
Width="100" Height="60" Fill="Coral"/>
<TextBlock Canvas.Left="350" Canvas.Top="60"
Text="Văn bản tự do" FontSize="16"/>
<Polygon Canvas.Left="100" Canvas.Top="150"
Points="0,0 60,0 30,50" Fill="MediumSeaGreen"/>
</Canvas>
</Window>
Thuộc tính đặc biệt:
Canvas.Left/Canvas.Top: Vị trí góc trên-tráiCanvas.Right/Canvas.Bottom: Vị trí góc dưới-phải (ưu tiên thấp hơn)Panel.ZIndex: Thứ tự chồng lớp (số lớn nằm trên)
Bảng so sánh nhanh
| Container | Khi nào dùng | Ưu điểm |
|---|---|---|
| StackPanel | Danh sách đơn giản | Dễ dàng, tự động căn chỉnh |
| WrapPanel | Danh sách động, tag cloud | Tự động xuống dòng |
| DockPanel | Layout ứng dụng cổ điển | Neo nhanh vào các cạnh |
| Grid | Hầu hết các trường hợp | Lin hoạt, hỗ trợ căn chỉnh phức tạp |
| Canvas | Vẽ đồ họa, game 2D | Điều khiển vị trí tuyệt đối |