Làm thế nào để sử dụng DockStyle.Fill cho các điều khiển tiêu chuẩn trong WPF?


92

Tôi được sử dụng từ các biểu mẫu cửa sổ, mà tôi tạo một bảng điều khiển, đặt các điều khiển bên trong nó và cung cấp cho chúng DockStyle.Fillđể tăng tối đa kích thước của chúng cho bảng điều khiển xung quanh.

Trong WPF tôi cũng muốn có như vậy. Tôi có một TabControl và tôi muốn kích thước của nó để điền vào càng nhiều biểu mẫu càng tốt. Tôi có một điều khiển ruy-băng (RibbonControlsLibrary) và muốn phần còn lại của biểu mẫu được lấp đầy bằng TabControl ở kích thước tối đa.

(Tôi không muốn gắn các điều khiển như gắn trong Visual Studio, chỉ là các cơ chế gắn cũ)

Câu trả lời:


183

WPF tương đương với WinForms 'DockStyle.Fill là:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Đây là mặc định cho hầu hết các điều khiển, vì vậy nói chung bạn không phải làm bất cứ điều gì để điều khiển WPF lấp đầy vùng chứa mẹ của nó : Chúng tự động làm như vậy. Điều này đúng với tất cả các vật chứa không ép con của họ đến kích thước tối thiểu.

Lỗi thường gặp

Bây giờ tôi sẽ giải thích một số lỗi phổ biến ngăn không cho hoạt HorizontalAlignment="Stretch" VerticalAlignment="Stretch"động như mong đợi.

1. Chiều cao hoặc chiều rộng rõ ràng

Một sai lầm phổ biến là chỉ định rõ ràng Chiều rộng hoặc Chiều cao cho một điều khiển. Vì vậy, nếu bạn có cái này:

<Grid>
  <Button Content="Why am I not filling the window?" Width="200" Height="20" />
  ...
</Grid>

Chỉ cần xóa các thuộc tính Chiều rộng và Chiều cao:

<Grid>
  <Button Content="Ahhh... problem solved" />
  ...
</Grid>

2. Bảng điều khiển ép chặt điều khiển đến kích thước tối thiểu

Một sai lầm phổ biến khác là để bảng điều khiển chứa điều khiển của bạn càng chặt càng tốt. Ví dụ: một StackPanel dọc sẽ luôn ép nội dung của nó theo chiều dọc khi chúng sẽ nhỏ đi:

<StackPanel>
  <Button Content="Why am I squished flat?" />
</StackPanel>

Thay đổi sang một Bảng điều khiển khác và bạn sẽ có thể tiếp tục:

<DockPanel>
  <Button Content="I am no longer squished." />
</DockPanel>

Ngoài ra, bất kỳ hàng hoặc cột Grid nào có chiều cao là "Tự động" cũng sẽ ép nội dung của nó theo hướng đó.

Một số ví dụ về các thùng chứa không bóp chặt con cái của họ là:

  • ContentControls không bao giờ bóp chết con của chúng (điều này bao gồm Border, Button, CheckBox, ScrollViewer và nhiều thứ khác)
  • Lưới với một hàng và cột
  • Lưới với các hàng và cột có kích thước "*"
  • DockPanel không bóp chết đứa con cuối cùng của nó
  • TabControl không bóp chết nội dung của nó

Một số ví dụ về các thùng chứa có thể bóp chặt con cái của họ là:

  • StackPanel ép theo hướng Định hướng của nó
  • Lưới có hàng hoặc cột có kích thước "Tự động" ép theo hướng đó
  • DockPanel ép tất cả trừ đứa con cuối cùng của nó theo hướng bến tàu của chúng
  • TabControl bóp tiêu đề của nó (những gì được hiển thị trên tab)

3. Chiều cao hoặc chiều rộng rõ ràng hơn nữa

Thật ngạc nhiên khi tôi thấy Grid hoặc DockPanel có chiều cao và chiều rộng rõ ràng, như thế này:

<Grid Width="200" Height="100">
  <Button Content="I am unnecessarily constrainted by my containing panel" />
</Grid>

Nói chung, bạn không bao giờ muốn cung cấp cho bất kỳ Bảng điều khiển nào một Chiều cao hoặc Chiều rộng rõ ràng. Bước đầu tiên của tôi khi chẩn đoán các vấn đề về bố cục là loại bỏ mọi Chiều cao hoặc Chiều rộng rõ ràng mà tôi có thể tìm thấy.

4. Cửa sổ là SizeToContent khi không nên

Khi bạn sử dụng SizeToContent, nội dung của bạn sẽ bị giảm xuống kích thước tối thiểu. Trong nhiều ứng dụng, điều này rất hữu ích và là sự lựa chọn chính xác. Nhưng nếu nội dung của bạn không có kích thước "tự nhiên" thì có thể bạn sẽ muốn bỏ qua SizeToContent.


Tôi đã để lại một câu hỏi liên quan đến bố cục mới khá phức tạp ở đây . Sau khi đọc câu trả lời của bạn ở đây, tôi nghĩ rằng bạn có thể tìm ra nó. Cheers
Berryl,

7
Câu trả lời xuất sắc! Tôi ước bằng cách nào đó tôi có thể cho bạn điểm thưởng. :)
Jim Raden

@Jim Raden: Bạn có thể thêm tiền thưởng cho câu hỏi này và gán các điểm đến Ray Burns;)
citronas

1
Lưu ý cho người đọc trong tương lai: nó sẽ không cập nhật trong dạng xem thiết kế cho đến khi bạn biên dịch lại.
David

"<Button Content =" Tại sao tôi không điền vào cửa sổ? "Width =" 200 "Height =" 20 "/>" khiến tôi kinh ngạc! XD
Jack Frost

7

Bạn có thể làm những gì bạn muốn chỉ bằng cách nói DockPanel LastChildFill="True"và sau đó đảm bảo rằng những gì bạn muốn trở thành chất độn thực sự là đứa con cuối cùng!

Grid là con thú của một bố cục mà bạn có thể làm hầu hết mọi thứ, nhưng DockPanel thường là lựa chọn phù hợp cho bảng bố cục ngoài cùng của bạn. Đây là một ví dụ mã psuedocode:

<DockPanel LastChildFill="True">
    <MyMenuBar DockPanel.Dock="Top"/>
    <MyStatus DockPanel.Dock="Bottom"/>

    <MyFillingTabControl />
</DockPanel>

5

chỉ cần bọc các điều khiển của bạn trong một lưới có hai hàng. Lưới sẽ tự động sử dụng tất cả không gian được cấp cho nó và bạn có thể xác định các hàng để chiếm tất cả không gian còn lại bằng cách cho chúng chiều cao là "*". Hàng đầu tiên trong ví dụ của tôi (Chiều cao = "Tự động") sẽ chiếm nhiều không gian theo nhu cầu của dải băng. Hy vọng rằng sẽ giúp.

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

  <Ribbon Grid.Row="0" />

  <TabPage Grid.Row="1" />
</Grid>

Bằng cách thêm thuộc tính "Grid.Row = .." vào các điều khiển con của lưới, chúng được gán cho các hàng của lưới. Sau đó, lưới sẽ kích thước của nó là con như được xác định bởi các định nghĩa hàng.


Đi vào đúng hướng, cảm ơn. Tôi đã quản lý để chèn Grid, nhưng bây giờ tôi cần nói với TabControl rằng nó có nên sử dụng tất cả kích thước vẫn có sẵn không? Làm thế nào tôi có thể đạt được điều đó?
citronas,

Bạn cần thêm thuộc tính "Grid.Row" cho TabControl và cung cấp cho định nghĩa hàng tương ứng có chiều cao là "*" - giống như được hiển thị trong ví dụ.
andyp

0

Tôi đã thử nhiều phương pháp ở đây nhưng không thể giải quyết vấn đề của tôi. (Điền vào kiểm soát khác trong kiểm soát)

Cho đến khi tôi tìm thấy

<Name_Control Height="auto" Width="auto"/>
//default
//HorizontalAlignment="Stretch" 
//VerticalAlignment="Stretch"

Thí dụ:

//UserControl:
<UserControl Name="UC_Test" Height="auto" Width="auto" />
//Grid: 
<Grid Name="Grid_test" Grid.ColumnSpan="2" Grid.Row="2" />
//Code: 
Grid_test.Children.Add(UC_Test);

Để thiết kế dễ dàng

<UserControl Name="UC_Test" Height="100" Width="100" />
//Code
Grid_test.Children.Add(UC_Test);
UC_Test.Width = Double.NaN;
UC_Test.Height = Double.NaN;
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.