相互关联的堆栈面板尺寸

发布于 2024-09-25 07:29:00 字数 1560 浏览 7 评论 0原文

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

有两列,

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

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

如果第一列中的框比第二列中堆叠的盒子的总高度短,盒子应该扩展以使两列具有相同的高度。

如果第二列的总高度比第一列中的框短,则第二列堆栈中的最后一项应展开,以便它们具有相同的高度。

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

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>

现在如果堆叠的列较高,则此方法效果很好,但如果第一列较高,则此方法不起作用,并且会出现间隙。知道如何处理这种相互高度依赖性吗?


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

I have a recursively defined user control that needs the following properties:

there are two columns

the first contains a single border around some text

the second column contains a stack of these same type of controls (the recursive part)

if the box in the first column is shorter than the total height of the stacked boxes in the second column, the box should expand to make both columns the same height.

If the total height of the second column is shorter than the box in the first column, then the last item in the second column's stack should expand so they are the same height.

so for example, it might look like this:

alt text

Ok, so far what I have done is create a horizontal stack panel where the first item is a dock-panel containing a border and text... the second column is a vertical stack panel bound to a sublist, creating the recursive user control... like this..

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

Where the requirement looks like this:

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

Now this works great if the stacked column is taller, but it doesn't work if the first column is taller, and I get gaps. Any idea how to handle this mutual height dependency?


Update:
So by adding a border around the right columns stack panel, I was able to see that the stackpanel actually did receive the min-height changes. However, even though there was room to expand, the children of the stack panel didn't automatically update. If I fix the minheight of the stack panel before hand to something large, the children fill up. What I need to figure out is how to update the chidren's height based on changes to the stack panel's min-height.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉薄对峙 2024-10-02 07:29:00

我认为此布局中的 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 的高度(当您将 TextBox 替换为其他元素,您需要设置最小高度以防止它们在为空时消失)。由于第三行是星形大小的,因此它将根据前两行排列后剩余的所有剩余垂直空间调整自身大小。因此,如果第一列中有一堆内容,第二列中的第三行就会变得更高。

编辑

实际上,在这种情况下甚至没有理由使用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>

I think the Grid in this layout does what you describe. I put it in a DockPanel so that you can see how it resizes. Try typing stuff into the text boxes and watch how it behaves:

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

All three rows of the Grid will have the height of a TextBox at a minimum (when you replace the TextBoxes with other elements, you'll need to set minimum heights to keep them from vanishing if they're empty). Since the third row is star-sized, it will size itself to all remaining vertical space left after the first two rows are arranged. So if there's a bunch of content in the first column, the third row in the second column gets taller.

Edit

Actually, there's no reason to even screw around with a Grid in this case: What you're describing is really the behavior of the 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文