【问题标题】:How to make DockPanel fill available space如何使 DockPanel 填充可用空间
【发布时间】: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 提供的所有可用空间的最佳方法是什么?

【问题讨论】:

    标签: .net wpf autosize dockpanel


    【解决方案1】:

    DockPanelWidth绑定到ListBoxItemActualWidth

    <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被拉伸
    • 我最终找到了您的第二种方法并走那条路线。
    • 如果您使用 Horizo​​ntalContentAlignment 而不是 Horizo​​ntalAlignment,则第二种方法有效。我编辑了答案。
    • 如果您的 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】:

      DockPanels 是邪恶的。将StackPanel/DockPanel 组合用于复杂布局的诱惑会导致“布局死胡同”。使用网格:

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

      我几乎只使用Grids,为每个“属于一起”的元素块使用单独的网格

      【讨论】:

      • 我不认为 DockPanel 是邪恶的,它们有时会非常有用......但我必须同意,在这种情况下它可能不是最好的选择
      • 当然这是主观的,它们不是 绝对 邪恶;)但是看看 Rich 已经去哪里了 - 使用 ItemContainerStyle(半高级的东西)来完成简单的任务 - 有点指示性...
      • 我一开始就考虑过网格。但是,如果 ListBox 很窄,或者 Name 或 Price 属性的值足够长,两个 TextBlock 最终会重叠它们的值。此外,我很难将在面板两端放置两个 TextBlock 归类为“复杂布局”。
      • 很抱歉对这篇旧帖子发表评论,但使用网格也是解决问题的简单且同样有效的解决方案。重叠问题是可以避免的。 +1
      • 这是一个旧答案,但我想我要指出的是,在 ListBox 的项目模板中使用网格或面板的问题在于它不是一个单一的元素;它是每个 ListBoxItem 的新元素,除非在模板中明确设置,否则它不会共享其他项的宽度。这使得在使用动态宽度时将 ItemContainerStyle 内容对齐设置为拉伸是必要的。
      猜你喜欢
      • 2016-12-02
      • 1970-01-01
      • 2016-08-13
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      • 2018-10-22
      • 2013-02-26
      相关资源
      最近更新 更多