0

考虑以下 XAML:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="*" MinHeight="100" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <ListBox>
      <ListBox.Items>
        <ListBoxItem>a</ListBoxItem>
        <!-- Another 11 items -->
      </ListBox.Items>
    </ListBox>
    <ListBox Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Visible">
      <ListBox.Items>
        <ListBoxItem>1</ListBoxItem>
        <!-- Another 23 items -->
      </ListBox.Items>
    </ListBox>
  </Grid>
</Window>

第二行中的 ListBox 将垂直滚动条显示为禁用,并简单地截断内容。

我希望它被限制在窗口的可见区域。如何做到这一点?

将第二个网格行的高度设置为 Auto 背后的合理性:如果有足够的空间,我希望第二个 ListBox 显示其所有内容而没有滚动条,并且第一个 ListBox 应该占用剩余空间。

4

1 回答 1

1

我认为没有任何方法可以在纯 XAML 中执行您想要的操作 - 您必须为两个列表框中的一个或另一个设置特定高度,或者为它们设置固定比例。

我认为你可以在后面的代码中使用一些代码来做你想做的事情。为您的 RowDefinitions 和 Listboxes 命名,如下所示,并订阅 GridSizedChanged 事件:

<Grid SizeChanged="GridSizeChanged">
    <Grid.RowDefinitions>
        <RowDefinition x:Name="row1"/>
        <RowDefinition x:Name="row2"/>
    </Grid.RowDefinitions>
    <ListBox x:Name="lb1">
        <ListBox.Items>
            <ListBoxItem>a</ListBoxItem>
        </ListBox.Items>
    </ListBox>
    <ListBox x:Name="lb2" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Visible">
        <ListBox.Items>
            <ListBoxItem>1</ListBoxItem>
            <!-- Another 23 items -->
        </ListBox.Items>
    </ListBox>
</Grid>

然后按以下方式处理事件:

private void GridSizeChanged(object sender, SizeChangedEventArgs e)
{
    double newHeight = e.NewSize.Height;
    int lb1ItemCount = lb1.Items.Count;
    int lb2ItemCount = lb2.Items.Count;
    row1.Height = new GridLength(newHeight * lb1ItemCount / (lb1ItemCount + lb2ItemCount));
    row2.Height = new GridLength(newHeight * lb2ItemCount / (lb1ItemCount + lb2ItemCount));
}

这将两个列表框的大小设置为与它们内部的项目数成正比。如果要将第一个列表框的最小大小设置为 100,则必须先做一些工作来设置该大小,然后将第二个大小基于第一个大小的计算值。

编辑: 我想我已经编写了一个 GridSizeChanged 版本,它完全符合您的要求。此版本会将 lb2 的高度设置为除顶部 100px 之外的整个网格(如果所需的列表框大小大于此),或者仅将其设置为自己所需的大小(如果较小)。然后,第一个列表框将填充所有剩余空间,并且根据您的要求具有 100 像素的最小高度,因为我们不允许 lb2 填充顶部 100 像素。

private void GridSizeChanged(object sender, SizeChangedEventArgs e)
{
    lb2.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    double lb2DesiredHeight = lb2.DesiredSize.Height;

    double newHeight = e.NewSize.Height;
    double lb2AvailableHeight = newHeight - 100;

    double lb2ActualHeight = Math.Min(lb2DesiredHeight, lb2AvailableHeight);
    row1.Height = new GridLength(newHeight - lb2ActualHeight);
    row2.Height = new GridLength(lb2ActualHeight);
}
于 2012-11-15T11:02:22.340 回答