Làm thế nào để có được các điều khiển trong WPF để lấp đầy không gian có sẵn?


304

Một số điều khiển WPF (như Button) dường như vui vẻ tiêu thụ tất cả không gian có sẵn trong thùng chứa của nó nếu bạn không chỉ định chiều cao cần có.

Và một số, giống như những thứ tôi cần sử dụng ngay bây giờ, (multiline) TextBoxListBoxdường như lo lắng hơn về việc chỉ lấy không gian cần thiết để phù hợp với nội dung của chúng, và không còn nữa.

Nếu bạn đặt những kẻ này vào một ô trong một ô UniformGrid, chúng sẽ mở rộng để phù hợp với không gian có sẵn. Tuy nhiên, UniformGridtrường hợp không đúng cho tất cả các tình huống. Điều gì nếu bạn có một lưới với một số hàng được đặt thành * chiều cao để phân chia chiều cao giữa chính nó và các hàng * khác? Điều gì sẽ xảy ra nếu bạn có a StackPanelvà bạn có a Label, a Listvà a Button, làm thế nào bạn có thể lấy danh sách để chiếm hết không gian không bị ăn bởi nhãn và nút?

Tôi nghĩ rằng đây thực sự sẽ là một yêu cầu bố trí cơ bản, nhưng tôi không thể tìm ra cách làm cho chúng lấp đầy khoảng trống mà chúng có thể (đặt chúng vào DockPanelvà đặt nó để lấp đầy cũng không hoạt động, dường như, vì các DockPanelchỉ chiếm không gian cần thiết cho subcontrols của nó).

Một giao diện thay đổi kích thước sẽ là khá khủng khiếp nếu bạn có để chơi với Height, Width, MinHeight, MinWidth, vv

Bạn có thể liên kết tài sản HeightWidthtài sản của bạn với ô lưới bạn chiếm không? Hoặc có một cách khác để làm điều này?


1
UniformGrid là tuyệt vời, thẻ goto mặc định mới của tôi. Tôi thích sự đơn giản của Stackpanels (nhắc nhở tôi về một div) nhưng thống nhất lưới thực hiện chính xác những gì tôi cần.
Terrance

Đồng phục lại. Điểm nhấn là Đồng phục. Có vẻ như bạn không thể điều chỉnh độ rộng cột không có chiều cao hàng. Nó chỉ phù hợp nếu mỗi phần nội dung có cùng kích thước. Tôi đã thay thế StackPanel của mình bằng Grid và Stretch sau đó hoạt động như tôi mong đợi.
pdschuller

Bài viết này đã giúp tôi kéo dài hộp văn bản.
jpaugh

Câu trả lời:


162

Mỗi điều khiển xuất phát từ Panelthực hiện logic bố cục riêng biệt được thực hiện trong Measure()Arrange():

  • Measure() xác định kích thước của bảng điều khiển và mỗi đứa con của nó
  • Arrange() xác định hình chữ nhật trong đó mỗi điều khiển biểu hiện

Đứa con cuối cùng DockPanellấp đầy không gian còn lại. Bạn có thể vô hiệu hóa hành vi này bằng cách đặt thuộc LastChildtính thành false.

Họ StackPanelyêu cầu mỗi đứa trẻ cho kích thước mong muốn của nó và sau đó xếp chúng. Bảng ngăn xếp gọi Measure()cho mỗi đứa trẻ, với kích thước có sẵn Infinityvà sau đó sử dụng kích thước mong muốn của trẻ.

Một Gridchiếm tất cả không gian có sẵn, tuy nhiên, nó sẽ đặt mỗi đứa trẻ đến kích thước mong muốn của chúng và sau đó đặt chúng vào trong ô.

Bạn có thể thực hiện logic bố cục của riêng mình bằng cách xuất phát Panelvà sau đó ghi đè MeasureOverride()ArrangeOverride().

Xem bài viết này cho một ví dụ đơn giản.


8
Liên kết hiện đã chết
user3690202

6
@ user3690202 Archive.org là bạn của bạn. Liên kết lại.
ruffin

4
Chủ đề vẫn tồn tại trong MSDN, nhưng liên kết đã thay đổi thành: docs.microsoft.com/en-us/dotnet/framework/wpf/controls/ Lỗi
Andrea Antonangeli

2
The last child of the DockPanel fills the remaining space: đây là chìa khóa còn thiếu cho sự hiểu biết của tôi. Tôi luôn luôn mặc dù phần tử không có Dock rõ ràng đã lấp đầy khoảng trống.
Phát hiện

238

Ngoài ra còn có một số thuộc tính bạn có thể thiết lập để buộc một điều khiển lấp đầy không gian có sẵn của nó khi nó không làm như vậy. Ví dụ: bạn có thể nói:

HorizontalContentAlignment="Stretch"

... Để buộc các nội dung của điều khiển kéo dài theo chiều ngang. Hoặc bạn có thể nói:

HorizontalAlignment="Stretch"

... Để buộc điều khiển tự kéo dài theo chiều ngang để lấp đầy cha mẹ của nó.


88
Bảng điều khiển khét tiếng nhất được đề cập trong tất cả các trường hợp này là StackPanel. Nó không chứa các thuộc tính ContentAlocation và đặt các con của nó thành Stretch sẽ không có hiệu lực bên trong lưới có kích thước sao. Rất bực bội. Gần như thể StackPanel là thùng chứa đầu tiên mà nhóm WPF đã viết và nó phải chịu đựng điều đó.
Brent Schooley

4
@Brent - àh! Tôi đã bị mắc kẹt khi cố gắng điền chính xác nội dung của stackpanel. cảm ơn! Tôi nghĩ rằng đó chỉ là một cái gì đó tôi đã làm rất sai.
Ashley Grenon

8
Bảng điều khiển @townsean Ngăn xếp rất hạn chế, bạn có thể có hành vi tương tự với việc kéo dài bằng cách sử dụng Đồng phục và đặt Hàng hoặc Cột thành 0
ForbesLindesay

2
@ Tuskan360 UniformGrid chỉ cho phép các ô có cùng kích thước. Tôi đã sử dụng một Grid cuối cùng, dường như để làm việc. Làm phiền làm thế nào StackPanel không làm những gì nó dường như được thiết kế.
TarkaDaal

4
@TarkaDaal yeh, UniformGrid nếu mọi thứ đều có cùng kích thước, Lưới nếu bạn muốn chỉ định kích thước tương đối phức tạp, bảng ngăn xếp để chỉ kích thước dựa trên nội dung và bỏ qua dung lượng có sẵn.
ForbesLindesay

18

Vâng, tôi đã tự mình tìm ra nó, ngay sau khi đăng, đó là cách ngượng ngùng nhất. :)

Có vẻ như mọi thành viên của StackPanel sẽ chỉ cần điền vào kích thước yêu cầu tối thiểu của nó.

Trong DockPanel, tôi đã cập cảng sai thứ tự. Nếu TextBox hoặc ListBox là mục được neo duy nhất không có căn chỉnh hoặc nếu chúng là mục cuối cùng được thêm vào, chúng sẽ lấp đầy khoảng trống còn lại như mong muốn.

Tôi rất thích thấy một phương pháp thanh lịch hơn để xử lý việc này, nhưng nó sẽ làm được.


Tôi chỉ muốn chỉ ra (về câu hỏi cũ này!) Rằng "không có sự liên kết" là cụm từ chính ở đây, ít nhất nó là dành cho tôi.
MikeBaz - MSFT

4

Sử dụng các thuộc tính bố trí ngang dọcdọc . Chúng kiểm soát cách một phần tử sử dụng không gian bên trong cha mẹ của nó khi có nhiều chỗ hơn so với yêu cầu của phần tử.

Ví dụ, chiều rộng của StackPanel sẽ rộng bằng phần tử rộng nhất mà nó chứa. Vì vậy, tất cả các yếu tố hẹp hơn có một chút không gian thừa. Các thuộc tính căn chỉnh kiểm soát những gì phần tử con làm với không gian thêm.

Giá trị mặc định cho cả hai thuộc tính là Stretch, do đó phần tử con được kéo dài để lấp đầy tất cả không gian có sẵn. Các tùy chọn bổ sung bao gồm Trái, Giữa và Phải đối với Ngang ngang và Trên cùng, Giữa và Dưới đối với Dọc dọc .


31
Nếu điều này luôn luôn đúng, câu hỏi ban đầu sẽ không được hỏi. Lấy ví dụ, một StackPanel nằm ngang với Nhãn và TextBox. Có thêm không gian bên phải của TextBox. TextBox được đặt thành Độ rộng tự động. Đặt Stretch cho Ngang ngang sẽ không làm cho TextBox lấp đầy khoảng trống còn lại.
Brent Schooley

Không có gì là luôn đúng nhưng câu trả lời này hoạt động cho nhu cầu của tôi: DockPanel, Image.
alehro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.