1

In a WPF Project I have a Grid defined with two rows each containing a ListBox. The RowDefinitions have their Height = '*' so equal space is allocated to each ListBox. What I would like to happen however, is that when either ListBox is not fully needing all its own space (through items being removed at runtime) then that 'spare' space is given over to the other ListBox.

So, using the code I list below, both ListBox's start off with equal space which is correct. Pressing the button deletes some entries from the top ListBox (topList), resulting in white space below the remaining 2 entries. It's this space I would like to be granted to the bottom ListBox. And vice versa.

XAML:

<Window x:Class="FiftyPercentSplit.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:FiftyPercentSplit"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid Height="200">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
   </Grid.RowDefinitions>

    <Button x:Name="btnDeleteFromTopList" Click="btnDeleteFromTopList_Click" Content="Delete from Top List"/>

    <ListBox  x:Name="topList" Grid.Row="1">
        <ListBoxItem>1</ListBoxItem>
        <ListBoxItem>2</ListBoxItem>
        <ListBoxItem>3</ListBoxItem>
        <ListBoxItem>4</ListBoxItem>
        <ListBoxItem>5</ListBoxItem>
        <ListBoxItem>6</ListBoxItem>
        <ListBoxItem>7</ListBoxItem>
        <ListBoxItem>8</ListBoxItem>
        <ListBoxItem>9</ListBoxItem>
    </ListBox>

    <ListBox  x:Name="bottomList" Grid.Row="2">
        <ListBoxItem>1</ListBoxItem>
        <ListBoxItem>2</ListBoxItem>
        <ListBoxItem>3</ListBoxItem>
        <ListBoxItem>4</ListBoxItem>
        <ListBoxItem>5</ListBoxItem>
        <ListBoxItem>6</ListBoxItem>
        <ListBoxItem>7</ListBoxItem>
        <ListBoxItem>8</ListBoxItem>
        <ListBoxItem>9</ListBoxItem>
    </ListBox>

</Grid>
</Window>

Code behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void btnDeleteFromTopList_Click(object sender, RoutedEventArgs e)
    {
        for (int i = 0; i < 7; i++)
        {
            topList.Items.RemoveAt(0);
        }
    }
}
4

2 回答 2

1

实际上,第二行应该表现为Auto-height 行。但是像 ListBox 这样的可滚动控件在 -height 行中不能很好地工作Auto——它们会无限增长并且不显示滚动。为了克服它,我通常必须设置MaxHeight.

在这种情况下,我留下了 2 个带有 Height="*" 的 RowDefinitions,使用带有名称的元素Measurer来获取行的实际高度并设置 Measurer 的MaxHeightfor topListfrom ActualHeight。另请注意,我使用了嵌套网格<RowDefinition Height="Auto"/>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Button x:Name="btnDeleteFromTopList" Click="btnDeleteFromTopList_Click" Content="Del"/>

    <Border Grid.Row="2" Name="Measurer"/>

    <Grid Grid.Row="1" Grid.RowSpan="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <ListBox  Grid.Row="0" x:Name="topList" VerticalAlignment="Top"
                  MaxHeight="{Binding ActualHeight, ElementName=Measurer}">

        </ListBox>

        <ListBox  x:Name="bottomList" Grid.Row="1">

        </ListBox>
    </Grid>       
</Grid>
  • 从示例中删除 ListBoxItems 以避免答案中的代码混乱
于 2017-03-06T18:17:08.060 回答
1

只需像这样使用 StackPanel 而不是 Grid :

    <Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel Height="200">

    <Button x:Name="btnDeleteFromTopList" Click="btnDeleteFromTopList_Click" Content="Delete from Top List"/>

    <ListBox  x:Name="topList" Grid.Row="1">
        <ListBoxItem>1</ListBoxItem>
        <ListBoxItem>2</ListBoxItem>
        <ListBoxItem>3</ListBoxItem>
        <ListBoxItem>4</ListBoxItem>
        <ListBoxItem>5</ListBoxItem>
        <ListBoxItem>6</ListBoxItem>
        <ListBoxItem>7</ListBoxItem>
        <ListBoxItem>8</ListBoxItem>
        <ListBoxItem>9</ListBoxItem>
    </ListBox>

    <ListBox  x:Name="bottomList" Grid.Row="2">
        <ListBoxItem>1</ListBoxItem>
        <ListBoxItem>2</ListBoxItem>
        <ListBoxItem>3</ListBoxItem>
        <ListBoxItem>4</ListBoxItem>
        <ListBoxItem>5</ListBoxItem>
        <ListBoxItem>6</ListBoxItem>
        <ListBoxItem>7</ListBoxItem>
        <ListBoxItem>8</ListBoxItem>
        <ListBoxItem>9</ListBoxItem>
    </ListBox>

</StackPanel>

于 2017-03-06T17:21:14.723 回答