2009-07-03 11 views
17

Tôi đang thử nội dung của giỏ hàng trong một số ItemsControl(ListBox). Để làm như vậy, tôi đã tạo ra những điều sau DataTemplate:Cách đặt DockPanel lấp đầy không gian có sẵn

<DataTemplate x:Key="Templates.ShoppingCartProduct" 
       DataType="{x:Type viewModel:ProductViewModel}"> 
    <DockPanel HorizontalAlignment="Stretch"> 
     <TextBlock DockPanel.Dock="Left" 
        Text="{Binding Path=Name}" 
        FontSize="10" 
        Foreground="Black" /> 
     <TextBlock DockPanel.Dock="Right" 
        Text="{Binding Path=Price, StringFormat=\{0:C\}}" 
        FontSize="10" 
        Foreground="Black" /> 
    </DockPanel> 
</DataTemplate> 

Khi các mục được hiển thị trong giỏ hàng của tôi tuy nhiên, Name, Price TextBlocks đang ngồi ngay bên cạnh nhau, và có một số lượng rất lớn của khoảng trắng ở phía bên tay phải.

Đã tự hỏi phương pháp nào tốt nhất để buộc DockPanel để kéo dài để lấp đầy tất cả không gian được cung cấp bởi ListItem là?

Trả lời

26

Bind các Width của DockPanel đến ActualWidth của ListBoxItem:

<DockPanel Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"> 
... 

Một tùy chọn: bạn có thể chỉ xác định lại ItemContainerStyle để các ListBoxItem được kéo dài theo chiều ngang:

<ListBox.ItemContainerStyle> 
    <Style TargetType="ListBoxItem"> 
     <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
    </Style> 
</ListBox.ItemContainerStyle> 
+0

Tôi đã thử sử dụng liên kết đó và dường như làm cho ListBoxItem liên tục phát triển về kích thước, khi xem bằng Snoop, tôi thấy chiều rộng của cả ListBoxItem và DockPanel vượt quá 300.000. –

+0

Hãy thử ràng buộc với ActualWidth của ListBox chính nó, sau đó ... –

+2

Oh, ok, tôi nhận được nó ... bạn phải đặt LastChildFill = "False" trên DockPanel, nếu không TextBlock thứ hai được kéo dài –

4

DockPanel s là ác. Cám dỗ sử dụng kết hợp StackPanel/DockPanel cho bố cục phức tạp dẫn đến "bố cục kết thúc chết". Sử dụng một lưới:

<Grid> 
    <TextBlock HorizontalAlignment="Left" 
... 
    <TextBlock HorizontalAlignment="Right" 
... 
/Grid> 

tôi sử dụng Grid là gần như độc quyền, sử dụng một mạng lưới riêng biệt cho mỗi khối của các yếu tố đó "thuộc về nhau"

+0

Tôi không nghĩ DockPanels là ác, đôi khi chúng có thể khá hữu ích ... tuy nhiên tôi phải đồng ý rằng nó có lẽ không phải là lựa chọn tốt nhất trong trường hợp đó –

+0

Tất nhiên đây là chủ quan và họ không phải là một _absolute_ ác;) Nhưng nhìn nơi Rich đã đi - sử dụng ItemContainerStyle (bán công cụ tiên tiến) cho nhiệm vụ đơn giản - kinda chỉ ... –

+0

Tôi đã xem xét một lưới ngay từ đầu. Tuy nhiên, với một ListBox hẹp, hoặc giá trị đủ dài cho các thuộc tính Name hoặc Price thì hai TextBlocks sẽ kết thúc chồng chéo các giá trị của chúng. Ngoài ra, tôi sẽ khó phân loại hai TextBlocks ở các đầu đối diện của bảng điều khiển dưới dạng "bố cục phức tạp". –

5

Những điều tốt đẹp về tấm dock là họ đã lấp đầy tất cả các không gian có sẵn . LastChildFill là true theo mặc định (nhưng tôi đặt nó dưới đây cho rõ ràng), do đó, chỉ cần không đặt thuộc tính DockPanel trên đứa trẻ cuối cùng, và nó sẽ lấp đầy không gian có sẵn.

<DockPanel HorizontalAlignment="Stretch" LastChildFill="true"> 
    <TextBlock DockPanel.Dock="Left" 
       Text="{Binding Path=Name}" 
       FontSize="10" 
       Foreground="Black" /> 
    <TextBlock 
       Text="{Binding Path=Price, StringFormat=\{0:C\}}" 
       FontSize="10" 
       Foreground="Black" /> 
</DockPanel>