2008-08-30 19 views
256

Một số điều khiển WPF (như Button) dường như vui vẻ tiêu thụ tất cả các không gian sẵn có trong 'container của nó nếu bạn không chỉ định chiều cao nó là có.Làm thế nào để có được điều khiển trong WPF để điền vào không gian có sẵn?

Và một số, giống như những gì tôi cần sử dụng ngay bây giờ, (multiline) TextBoxListBox có vẻ lo lắng hơn về việc chỉ chiếm 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 người này vào ô trong một UniformGrid, chúng sẽ mở rộng để vừa với không gian có sẵn. Tuy nhiên, UniformGrid trường hợp không phù hợp với mọi tình huống. Điều gì sẽ xảy ra nếu bạn có một mạng 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? Nếu bạn có số StackPanel và bạn có một số Label, ListButton, làm cách nào bạn có thể lấy danh sách để chiếm hết không gian không được nhãn và nút? Tôi có thể nghĩ rằng điều này thực 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 không gian mà chúng có thể (đặt chúng trong DockPanel và đặt nó vào cũng không hoạt động , có vẻ như, vì DockPanel chỉ chiếm không gian cần thiết cho 'các phụ lục' của nó.

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

Bạn có thể ràng buộc HeightWidth bạn tính đến các tế bào lưới bạn chiếm? Hay có cách nào khác để làm điều này?

+1

UniformGrid thật 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 tôi về một div) nhưng Grid thống nhất thực hiện chính xác những gì tôi cần. – Terrance

Trả lời

134

Mỗi kiểm soát phát sinh từ Panel thực hiện luận lý bố trí riêng biệt thực hiện trong Measure()Arrange():

  • Measure() xác định kích cỡ của bảng điều khiển và mỗi người trong số con của nó
  • Arrange() xác định hình chữ nhật trong đó mỗi kiểm soát renders

Đứa trẻ cuối cùng của DockPanel lấp đầy không gian còn lại. Bạn có thể tắt hành vi này bằng cách đặt thuộc tính LastChild thành false.

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

A Grid chiếm tất cả không gian có sẵn, tuy nhiên, nó sẽ đặt mỗi đứa trẻ theo kích thước mong muốn và sau đó căn giữa chúng trong ô.

Bạn có thể triển khai logic bố cục của riêng mình bằng cách lấy từ Panel và sau đó ghi đè MeasureOverride()ArrangeOverride().

Xem this article để có ví dụ đơn giản.

+4

Liên kết giờ đã chết – user3690202

+3

@ user3690202 Archive.org là bạn của bạn. Liên kết được reanimated. – ruffin

+0

Chủ đề vẫn tồn tại trong MSDN, nhưng liên kết đã thay đổi thành: https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/how-to-create-a-custom-panel-element –

14

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

Dường như mọi thành viên của StackPanel sẽ chỉ đ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 nhật mọi thứ theo thứ tự sai. 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 được thêm cuối cùng, chúng sẽ điền vào khoảng trống còn lại như mong muốn.

Tôi rất muốn thấy một phương pháp xử lý trang nhã hơn, nhưng nó sẽ thực hiện.

+0

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à một cụm từ quan trọng ở đây, ít nhất nó là dành cho tôi. –

188

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

HorizontalContentAlignment="Stretch" 

... để buộ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 bản thân kiểm soát kéo dài theo chiều ngang để lấp đầy bố mẹ.

+63

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 ContentAlignment và thiết lập các con của nó thành Stretch sẽ không có tác dụng bên trong một lưới có kích thước ngôi sao. Rất bực bội. Nó gần như là nếu StackPanel là container đầu tiên mà nhóm WPF đã viết và nó bị cho là trường hợp đó. –

+3

@Brent - ahh! Tôi đã cố gắng để có được nội dung của stackpanel của tôi điền vào một cách chính xác. cảm ơn! Tôi nghĩ đó chỉ là điều tôi đã làm rất sai. –

+6

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

0

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

Chiều rộng của một chồng xếp chồng, ví dụ, 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 dư thừa. Các thuộc tính căn chỉnh điều khiển phần tử con làm gì với không gian thừa.

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 Left, Center and Right cho HorizontalAlignment và trên cùng, giữa và dưới cho VerticalAlignment.

+24

Nếu điều này luôn đúng, câu hỏi ban đầu sẽ không được hỏi. Lấy ví dụ, một StackPanel ngang với một Label và một TextBox. Có thêm không gian ở bên phải của TextBox. TextBox được đặt thành Độ rộng tự động. Thiết lập Stretch cho HorizontalAlignment sẽ không làm cho TextBox lấp đầy không gian còn lại. –