WPF – Grid Layout Control

Là một layout control linh hoạt và hiệu quả nhất, Grid bố trí các control bên trong nó theo dạng bảng gồm các dòng và cột. Ngoài ra, bạn có thể thay đổi kích thước của dòng và cột trong quá trình thực thi với GridSplitter.

Định nghĩa dòng và cột

Bước đầu tiên khi làm việc với Grid layout control là bạn phải định nghĩa cấu trúc bao gồm các dòng và cột cũng như kích thước của chúng. Các đối tượng dòng, cột này được lưu trong hai collection là Grid.RowDefinitions và Grid.ColumnDefinitions.

Kích thước của dòng, cột được xác định bằng ba cách:

–       Cố định: sử dụng giá trị số với đơn vị là 1/96 inch.

–       Auto: Dòng/cột sẽ có kích thước vừa đủ để chứa các control bên trong.

–       Tỷ lệ: Dùng dấu sao (*) để xác định tỉ lệ. Giá trị của * được tính bằng kích thước còn lại của Grid chia cho tổng số phần được chia.

Ví dụ sau định nghĩa một Grid control với bốn dòng. Dòng đầu có chiều cao tự động (bằng với chiều cao lớn nhất của các control trong dòng đó). Dòng thứ hai có chiều cao bằng 50. Chiều cao còn lại của Grid được chia thành 3 phần: 2 phần cho dòng thứ ba và 1 phần cho dòng cuối.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="50" />
        <RowDefinition Height="*" />
        <RowDefinition Height="0.5*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
</Grid>

Với cách chia theo tỷ lệ, sẽ rõ ràng hơn nếu bạn sử dụng hoàn toàn số nguyên để xác định. Chẳng hạn với ví dụ trên, phần định nghĩa dòng có thể được viết lại thành:

<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="50" />
    <RowDefinition Height="2*" />
    <RowDefinition Height="*" />
</Grid.RowDefinitions>

Bố trí các control trong Grid

Khi được thêm vào trong Grid, các control có thể sử dụng hai attached property là Grid.Row và Grid.Column để xác định chỉ số dòng/cột của ô sẽ chứa chúng. Các chỉ số dòng/cột này được tính từ 0.

<Grid ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="2*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Button Grid.Row="0" Grid.Column="0">Button 1</Button>
    <Button Grid.Row="1" Grid.Column="1">Button 2</Button>
    <Button Grid.Row="2" Grid.Column="2">Button 3</Button>
</Grid>

Spanning dòng và cột

Sử dụng hai attached property là Grid.RowSpan và Grid.ColumSpan để xác định số lượng ô theo dòng/cột mà một control có thể nằm trong đó. Một điểm lưu ý là các ô của Grid không bị gộp thành một như trong html table, chỉ có control là được mở rộng thêm không gian chứa nó qua các ô khác. Vì vậy, bạn có thể truy xuất đến các ô theo chỉ số như thứ tự chúng được định nghĩa.

<Grid ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Button Background="Azure" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2">Button 1</Button>
    <Button Background="LightGreen" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2">Button 2</Button>
    <Button Background="Orange" Grid.Row="2" Grid.Column="2" Grid.RowSpan="2">Button 3</Button>
</Grid>

Kết quả:

Thay đổi kích thước dòng và cột (lúc runtime)

Bằng cách thêm các control GridSplitter vào Grid, bạn có thể di chuyển các GridSplitter và điều này làm cho kích thước của các dòng/cột thay đổi theo. Một vài thuộc tính của GridSplitter mà bạn cần quan tâm:

–       ResizeDirection: hướng thay đổi kích thước, gồm ba giá trị: Auto, Column và Row.

–       ShowsPreview: giá trị false sẽ cập nhật sự thay đổi kích thước của các dòng/cột khi bạn di chuyển GridSplitter.

–       Height/Width và VerticalAlignment/HorizontalAlignment: sử dụng để xác định kích thước, canh lề của GridSplitter tùy theo hướng di chuyển.

Ví dụ sau cho thấy việc sử dụng hai GridSplitter. GridSplitter đầu tiên được chèn vào cột thứ hai và GridSplitter thứ hai chèn vào dòng thứ hai trong Grid. Để ý rằng trong phần định nghĩa, tôi xác định kích thước của dòng/cột vừa đủ để chứa các GridSplitter.

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition Height="10" />
    <RowDefinition />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition />
    <ColumnDefinition Width="10" />
    <ColumnDefinition />
  </Grid.ColumnDefinitions>

  <Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="3">Left</Button>
  <Button Grid.Row="0" Grid.Column="2">Right</Button>
  <Button Grid.Row="2" Grid.Column="2">Right</Button>

  <GridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="3"
   Width="3" HorizontalAlignment="Center"
   ShowsPreview="False"></GridSplitter>

  <GridSplitter Grid.Row="1" Grid.Column="2"  Height="3"
    VerticalAlignment="Center" HorizontalAlignment="Stretch"
   ShowsPreview="False" ResizeDirection="Auto"></GridSplitter>
</Grid>

Kết quả:

Đồng bộ kích thước các dòng, cột của nhiều Grid

Khi định nghĩa dòng/cột, bạn có thể dùng thuộc tính SharedSizeGroup nhằm xác định một tên nhóm để các dòng/cột thuộc cùng nhóm luôn có kích thước bằng nhau, mặc dù chúng nằm trong các Grid control khác nhau.

Khi dùng phương pháp này, bạn hãy nhớ đặt thuộc tính Grid.IsSharedSizeScope thành true cho control chứa các Grid cần đồng bộ kích thước dòng/cột. Thuộc tính Grid.IsSharedSizeScope sẽ xác định rằng các control con của nó thuộc phạm vi chia sẻ kích thước với nhau.

Ví dụ sau cho thấy cách để hai cột đầu tiên của hai Grid control luôn có chiều rộng bằng nhau:

<StackPanel Grid.IsSharedSizeScope="True">

        <Label>Grid 1:</Label>
        <Grid Background="LightYellow" ShowGridLines="True">

            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="ColGroup" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Button Width="100" Height="50">Width=100</Button>
            <Button Width="100" Height="50" Margin="5,0,5,0" Grid.Column="1" >Width=100</Button>
        </Grid>

        <Label>Grid 2:</Label>
        <Grid Background="LightYellow"  ShowGridLines="True">

            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="ColGroup" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Button Width="200" Height="50" Margin="5,0,5,0">Width=200</Button>
            <Button Width="200" Height="50" Margin="5,0,5,0" Grid.Column="1" >Width=200</Button>
        </Grid>
</StackPanel>

Kết quả:

https://yinyangit.wordpress.com

Advertisements

2 thoughts on “WPF – Grid Layout Control

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 )

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 )

Google+ photo

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

Connecting to %s