相关的堆栈面板尺寸

时间:2010-09-27 23:38:10

标签: c# wpf stackpanel sizing

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

有两列

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

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

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

如果第二列的总高度比第一列中的框小,那么第二列堆栈中的最后一项应该展开,因此它们的高度相同。

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

alt text

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

<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>

现在,如果堆叠的柱子更高,这可以很好地工作,但如果第一列更高,则它不起作用,并且我得到间隙。知道如何处理这种相互高度依赖吗?


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

1 个答案:

答案 0 :(得分: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>