【问题标题】:inter related stack panel sizing相互关联的堆栈面板尺寸
【发布时间】:2010-09-27 23:38:10
【问题描述】:

我有一个递归定义的用户控件,它需要以下属性:

有两列

第一个包含一些文本周围的单个边框

第二列包含一堆这些相同类型的控件(递归部分)

如果第一列中的框比第二列中堆叠框的总高度短,则框应展开以使两列高度相同。

如果第二列的总高度小于第一列中的框,则第二列堆栈中的最后一项应展开,使其高度相同。

例如,它可能看起来像这样:

好的,到目前为止,我所做的是创建一个水平堆栈面板,其中第一项是包含边框和文本的停靠面板...第二列是绑定到子列表的垂直堆栈面板,创建递归用户控制……像这样……

<StackPanel Orientation="Horizontal" Background="AliceBlue">
        <local:TMRequirementView Requirement="{Binding Baseline}" />
        <StackPanel Orientation="Vertical">
            <ItemsControl ItemsSource="{Binding Requirements}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <local:TMGridView Baseline="{Binding}" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>

需求如下所示:

    <DockPanel>
        <Border MinHeight="50"
                BorderBrush="Black" BorderThickness="2">
            <TextBlock Text="{Binding Description}" 
                       TextWrapping="Wrap" Background="Transparent" Height="Auto" />
        </Border>
    </DockPanel>

现在,如果堆叠的列更高,这很有效,但如果第一列更高,它就不起作用了,我会得到间隙。知道如何处理这种相互的高度依赖性吗?


更新: 因此,通过在右侧列堆栈面板周围添加边框,我能够看到堆栈面板实际上确实收到了最小高度更改。但是,即使有扩展空间,堆栈面板的子项也不会自动更新。如果我事先将堆栈面板的最小高度固定为较大的东西,孩子们就会填满。我需要弄清楚的是如何根据堆栈面板最小高度的变化来更新孩子的高度。

【问题讨论】:

  • 所以我想也许将第二列堆栈面板的 minheight 参数设置为第一列高度参数,但它抱怨......有什么想法吗?
  • height命令可以是NaN,我尝试绑定ActualHeight属性,但无济于事。

标签: c# wpf stackpanel sizing


【解决方案1】:

我认为此布局中的 Grid 符合您的描述。我把它放在DockPanel 中,这样你就可以看到它是如何调整大小的。尝试在文本框中输入内容并观察其行为:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <DockPanel>  
    <Grid DockPanel.Dock="Top">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
      <TextBox AcceptsReturn="True" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3"></TextBox>
      <TextBox AcceptsReturn="True" Grid.Row="0" Grid.Column="1"></TextBox>
      <TextBox AcceptsReturn="True" Grid.Row="1" Grid.Column="1"></TextBox>
      <TextBox AcceptsReturn="True" Grid.Row="2" Grid.Column="1"></TextBox>
    </Grid>
    <TextBlock/>
  </DockPanel>
</Page>

Grid 的所有三行至少具有TextBox 的高度(当您将 TextBoxes 替换为其他元素时,您需要设置最小高度以防止它们消失空的)。由于第三行是星形大小,因此它将自己调整为排列前两行后剩余的所有剩余垂直空间。所以如果第一列有一堆内容,第二列的第三行会变高。

编辑

实际上,在这种情况下,甚至没有理由使用Grid:您所描述的实际上是DockPanel 的行为:

<DockPanel>
  <DockPanel DockPanel.Dock="Top">      
    <DockPanel.Resources>
      <Style TargetType="Label">
        <Setter Property="DockPanel.Dock" Value="Top"/>
        <Setter Property="Background" Value="Lavender"/>
        <Setter Property="Margin" Value="1"/>
      </Style>
    </DockPanel.Resources>
    <DockPanel LastChildFill="True">
      <Label>Foo</Label>
    </DockPanel>
    <DockPanel LastChildFill="True">
      <Label>Foo</Label>
      <Label>Bar</Label>
      <Label>Baz</Label>
      <Label>Bat</Label>
    </DockPanel>
  </DockPanel>
  <Label/>
</DockPanel>

【讨论】:

  • 我最初有一个网格,但是在递归元素的数据绑定方面遇到了很多麻烦,我最终切换到堆栈面板方法......我可以按照你的建议重新审视这个,但是如果您还碰巧想到了一种使用堆栈面板进行格式化的方法,请告诉我!
  • 所以我遇到了和上次一样的问题。如何将网格绑定到 XAML 中的动态行定义?
猜你喜欢
  • 2018-10-27
  • 2011-07-12
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多