2010-07-09 30 views
74

Tôi rất mới đối với WPF. Tôi được sử dụng từ các hình thức cửa sổ, mà tôi tạo ra một bảng điều khiển, đặt điều khiển bên trong nó và cung cấp cho họ DockStyle.Fill để tối đa ra kích thước của họ để các bảng điều khiển xung quanh.Làm thế nào để sử dụng DockStyle.Fill cho các điều khiển tiêu chuẩn trong WPF?

Trong WPF, tôi muốn giống nhau. Tôi có một tab kiểm soát và tôi muốn kích thước của nó để điền vào càng nhiều hình thức 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 điền bằng điều khiển tab ở kích thước tối đa.

(Tôi không muốn bến điều khiển giống như docking trong Visual Studio, chỉ cũ cơ chế docking)

Trả lời

157

Các WPF tương đương với DockStyle.Fill WinForms' 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 cần phải làm bất cứ điều gì ở tất cả để có một điều khiển WPF điền vào container cha của nó: Họ làm như vậy tự động. Điều này đúng với tất cả các thùng chứa không ép con cái của chúng đến kích thước tối thiểu.

Những sai lầm

bây giờ tôi sẽ giải thích một số sai lầm phổ biến mà ngăn chặn HorizontalAlignment="Stretch" VerticalAlignment="Stretch" từ làm việc như mong đợi.

1. Explicit Height hoặc Width

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

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

Chỉ cần loại bỏ các Width và các thuộc tính Height:

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

2. bảng Chứa ép kiểm soát kích thước tối thiểu

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

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

Change to Panel khác và bạn sẽ được tốt để đi:

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

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

Một số ví dụ về các container mà không bóp con cái của họ là:

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

Một số ví dụ về các container mà làm bóp con cái của họ là:

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

3. Chiều cao Explicit hoặc Rộng hơn nữa ra

Thật ngạc nhiên bao nhiêu lần tôi nhìn thấy lưới hoặc DockPanel đưa ra một chiều cao rõ ràng và chiều 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ỳ Panel 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 vấn đề bố cục là xóa mọi Chiều cao hoặc Chiều rộng rõ ràng mà tôi có thể tìm thấy.

4. Window là SizeToContent khi nó không phải là

Khi bạn sử dụng SizeToContent, nội dung của bạn sẽ được vắt đến 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 đúng đắn. 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.

+0

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] (http://stackoverflow.com/questions/3326623/multiple-grid-layout-wpf). Sau khi đọc câu trả lời của bạn ở đây đang nghĩ rằng bạn có thể tìm ra nó. Chúc mừng – Berryl

+5

Câu trả lời tuyệt vời! Tôi ước tôi bằng cách nào đó có thể cho bạn điểm thưởng. :) –

+0

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

4

chỉ quấn điều khiển của bạn trong một mạng lưới với hai hàng. Lưới sẽ tự động sử dụng tất cả không gian cho nó và bạn có thể xác định các hàng để chiếm hết không gian còn lại bằng cách cho chúng một chiều cao "*". Hàng đầu tiên trong ví dụ của tôi (Height = "Auto") sẽ chiếm nhiều không gian khi băng cần thiết. 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 điều khiển con của lưới mà chúng được chỉ định cho các hàng của lưới. Sau đó, lưới sẽ kích thước nó là trẻ em như được xác định bởi các định nghĩa hàng.

+0

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

+0

Bạn cần thêm thuộc tính "Grid.Row" cho TabControl và đưa ra định nghĩa hàng tương ứng với chiều cao "*" - giống như trong ví dụ. – andyp

6

Bạn có thể làm những gì bạn muốn bằng cách chỉ nói DockPanelLastChildFill="True" và sau đó đảm bảo những gì bạn muốn làm phụ là thực sự là đứa trẻ cuối cùng!

Lưới là con thú của bố cục mà bạn có thể thực hiện nhiều nhất, nhưng DockPanel thường là lựa chọn đúng cho bảng điều khiển bố cục ngoài cùng của bạn. Dưới đây là một ví dụ psuedocode:

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

    <MyFillingTabControl /> 
</DockPanel> 
+0

cảm ơn sự giúp đỡ của bạn – citronas

0

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

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

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

Ví 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); 

Đối với 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; 
Các vấn đề liên quan