如何使 DockPanel 填充可用空间
Posted
技术标签:
【中文标题】如何使 DockPanel 填充可用空间【英文标题】:How to make DockPanel fill available space 【发布时间】:2010-11-08 00:07:31 【问题描述】:我正在尝试ItemsControl(ListBox)
中的购物车内容。为此,我创建了以下DataTemplate
:
<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>
当商品显示在我的购物车中时,名称和价格TextBlocks
并排放置,右侧有大量空白。
想知道强制DockPanel
伸展以填充ListItem
提供的所有可用空间的最佳方法是什么?
【问题讨论】:
【参考方案1】:将DockPanel
的Width
绑定到ListBoxItem
的ActualWidth
:
<DockPanel Width="Binding ActualWidth, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type ListBoxItem">
...
另一种选择:您可以重新定义ItemContainerStyle
,使ListBoxItem
水平拉伸:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
【讨论】:
我尝试使用该绑定,它似乎导致 ListBoxItem 的大小不断增长,当使用 Snoop 查看时,我看到 ListBoxItem 和 DockPanel 的宽度都超过了 300,000。 哦,好的,我明白了...你必须在DockPanel上设置LastChildFill="False",否则第二个TextBlock被拉伸 我最终找到了您的第二种方法并走那条路线。 如果您使用 HorizontalContentAlignment 而不是 HorizontalAlignment,则第二种方法有效。我编辑了答案。 如果您的 ListBox 被缩小,第一种方法不起作用。实际大小保持在最大值。【参考方案2】:停靠面板的好处是它们已经填满了所有可用空间。 LastChildFill 默认为 true(但为了清楚起见,我在下面设置了它),所以不要在最后一个孩子上设置 DockPanel 属性,它会填充可用空间。
<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>
【讨论】:
【参考方案3】:DockPanel
s 是邪恶的。将StackPanel/DockPanel
组合用于复杂布局的诱惑会导致“布局死胡同”。使用网格:
<Grid>
<TextBlock HorizontalAlignment="Left"
...
<TextBlock HorizontalAlignment="Right"
...
/Grid>
我几乎只使用Grid
s,为每个“属于一起”的元素块使用单独的网格
【讨论】:
我不认为 DockPanel 是邪恶的,它们有时会非常有用......但我必须同意,在这种情况下它可能不是最好的选择 当然这是主观的,它们不是 绝对 邪恶;)但是看看 Rich 已经去哪里了 - 使用 ItemContainerStyle(半高级的东西)来完成简单的任务 - 有点指示性... 我一开始就考虑过网格。但是,如果 ListBox 很窄,或者 Name 或 Price 属性的值足够长,两个 TextBlock 最终会重叠它们的值。此外,我很难将在面板两端放置两个 TextBlock 归类为“复杂布局”。 很抱歉对这篇旧帖子发表评论,但使用网格也是解决问题的简单且同样有效的解决方案。重叠问题是可以避免的。 +1 这是一个旧答案,但我想我要指出的是,在 ListBox 的项目模板中使用网格或面板的问题在于它不是一个单一的元素;它是每个 ListBoxItem 的新元素,除非在模板中明确设置,否则它不会共享其他项的宽度。这使得在使用动态宽度时将 ItemContainerStyle 内容对齐设置为拉伸是必要的。以上是关于如何使 DockPanel 填充可用空间的主要内容,如果未能解决你的问题,请参考以下文章