C# Can';我不明白高度和能见度的工作原理

C# Can';我不明白高度和能见度的工作原理,c#,wpf,C#,Wpf,我创建了一个示例应用程序: <Window x:Class="WpfApplication1.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/expre

我创建了一个示例应用程序:

<Window x:Class="WpfApplication1.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:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="525">
  <Window.Resources>
    <local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
  </Window.Resources>
    <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition /> <!-- Height="Auto" -->
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Text="Some Header Text" />
    <Grid Grid.Row="1">
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
      </Grid.RowDefinitions>
      <CheckBox Grid.Row="0" x:Name="switch" Content="Switch" IsChecked="True" />
      <ListView Grid.Row="1" Visibility="{Binding Path=IsChecked, ElementName=switch, Converter={StaticResource BooleanToVisibilityConverter}}" >
        <ListViewItem Content="11111111"/>
        <ListViewItem Content="22222222"/>
        <ListViewItem Content="33333333"/>
        <ListViewItem Content="44444444"/>
        <ListViewItem Content="55555555"/>
        <ListViewItem Content="66666666"/>
      </ListView>
      <ListView Grid.Row="2">
        <ListViewItem Content="aaaaaaaa"/>
        <ListViewItem Content="bbbbbbbb"/>
        <ListViewItem Content="cccccccc"/>
        <ListViewItem Content="dddddddd"/>
        <ListViewItem Content="eeeeeeee"/>
        <ListViewItem Content="ffffffff"/>
      </ListView>
    </Grid>
    <TextBox Grid.Row="2" Text="Some Footer Text" />
  </Grid>
</Window>

BooleanToVisibilityConverter将
true
转换为
Visible
,将
false
转换为
折叠

如果我按原样执行代码,那么两个列表框都是可见的,并且它们具有相同的高度和滚动条。这正是我所期望的。但是,如果取消选中该复选框,则顶部列表框将消失,但行不会折叠

当我添加
Height=“Auto”
(在第15行)时,顶部列表框的行为与预期一样-它消失,第二个列表框“上升”。但如果选中该复选框,则所有控件都以其全尺寸显示。第二个列表框的底部在窗口之外,没有滚动条,页脚不再可见(因为它在窗口区域之外)

我的目标是通过滚动条使两个列表框都可见,并让顶部的列表框通过复选框折叠。
我做错了什么?

您的问题是,您可以隐藏
列表视图,但不能隐藏周围的
网格行。因此,
列表视图
被折叠,但行没有折叠,行的高度仍然设置为
*

您无法轻松隐藏
网格行
。只有在代码隐藏中实现它,这才是可能的。我不确定你是否真的想那样做。这将是一个关于如何在代码隐藏中实现这一点的解释

对您来说,最简单的解决方案是使用不同的周围容器。例如,在
列表视图上设置一个
堆栈面板
,并设置一个
最大高度
,这样就不会显示所有元素。然后可见性按预期工作

<Window x:Class="WpfApp1.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:wpfApp1="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="250" Width="525">
<Window.Resources>
    <wpfApp1:BooleanConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <!-- Height="Auto" -->
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Text="Some Header Text" />
    <StackPanel Grid.Row="1">
        <CheckBox  x:Name="switch" Content="Switch" IsChecked="True" />
        <ListView  Visibility="{Binding Path=IsChecked, ElementName=switch, Converter={StaticResource BooleanToVisibilityConverter}}" MaxHeight="70">
            <ListViewItem Content="11111111"/>
            <ListViewItem Content="22222222"/>
            <ListViewItem Content="33333333"/>
            <ListViewItem Content="44444444"/>
            <ListViewItem Content="55555555"/>
            <ListViewItem Content="66666666"/>
        </ListView>
        <ListView  MaxHeight="70">
            <ListViewItem Content="aaaaaaaa"/>
            <ListViewItem Content="bbbbbbbb"/>
            <ListViewItem Content="cccccccc"/>
            <ListViewItem Content="dddddddd"/>
            <ListViewItem Content="eeeeeeee"/>
            <ListViewItem Content="ffffffff"/>
        </ListView>
    </StackPanel>
    <TextBox Grid.Row="2" Text="Some Footer Text" />
</Grid>


在这种情况下还有另一个因素:带有
Height=“*”
的行定义占用空间,即使该行中没有可见元素(或者甚至根本没有元素)。这就是网格的工作原理

介绍另一个面板:带有1列的UniformGrid。当两个ListView都可见时,UniformGrid将为它们提供相等的高度;当第一个ListView隐藏时,UniformGrid将为第二个ListView提供整个高度

<Grid Grid.Row="1">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <CheckBox Grid.Row="0" x:Name="switch" Content="Switch" IsChecked="True" />
  <UniformGrid Columns="1" Grid.Row="1" >
   <ListView Visibility="{Binding Path=IsChecked, ElementName=switch, Converter={StaticResource BooleanToVisibilityConverter}}" >
    <ListViewItem Content="11111111"/>
    <ListViewItem Content="22222222"/>
    <ListViewItem Content="33333333"/>
    <ListViewItem Content="44444444"/>
    <ListViewItem Content="55555555"/>
    <ListViewItem Content="66666666"/>
   </ListView>
   <ListView>
    <ListViewItem Content="aaaaaaaa"/>
    <ListViewItem Content="bbbbbbbb"/>
    <ListViewItem Content="cccccccc"/>
    <ListViewItem Content="dddddddd"/>
    <ListViewItem Content="eeeeeeee"/>
    <ListViewItem Content="ffffffff"/>
   </ListView>
  </UniformGrid>
</Grid>

另一种选择是在第一个ListView折叠时更改第二个ListView行和行跨度:

<Grid Grid.Row="1">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <CheckBox Grid.Row="0" x:Name="switch" Content="Switch" IsChecked="True" />
  <ListView Grid.Row="1" Visibility="{Binding Path=IsChecked, ElementName=switch, Converter={StaticResource BooleanToVisibilityConverter}}" >
    <ListViewItem Content="11111111"/>
    <ListViewItem Content="22222222"/>
    <ListViewItem Content="33333333"/>
    <ListViewItem Content="44444444"/>
    <ListViewItem Content="55555555"/>
    <ListViewItem Content="66666666"/>
  </ListView>
  <ListView>
    <ListView.Style>
     <Style TargetType="ListView">
      <Setter Property="Grid.Row" Value="2"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsChecked, ElementName=switch}" Value="False">
          <Setter Property="Grid.Row" Value="1"/>
          <Setter Property="Grid.RowSpan" Value="2"/>
        </DataTrigger>
      </Style.Triggers>
     </Style>
    </ListView.Style>
    <ListViewItem Content="aaaaaaaa"/>
    <ListViewItem Content="bbbbbbbb"/>
    <ListViewItem Content="cccccccc"/>
    <ListViewItem Content="dddddddd"/>
    <ListViewItem Content="eeeeeeee"/>
    <ListViewItem Content="ffffffff"/>
  </ListView>
</Grid>

当选中
复选框时,可以使用
Style
Height
Height
设置为
0
。试试这个:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition>
            <RowDefinition.Style>
                <Style TargetType="RowDefinition">
                    <Setter Property="Height" Value="*" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsChecked, ElementName=switch}" Value="False">
                            <Setter Property="Height" Value="0" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </RowDefinition.Style>
        </RowDefinition>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Text="Some Header Text" />
    <CheckBox Grid.Row="1" x:Name="switch" Content="Switch" IsChecked="True" />
    <ListView Grid.Row="2" Visibility="{Binding Path=IsChecked, ElementName=switch, Converter={StaticResource BooleanToVisibilityConverter}}" >
        <ListViewItem Content="11111111"/>
        <ListViewItem Content="22222222"/>
        <ListViewItem Content="33333333"/>
        <ListViewItem Content="44444444"/>
        <ListViewItem Content="55555555"/>
        <ListViewItem Content="66666666"/>
    </ListView>
    <ListView Grid.Row="3">
        <ListViewItem Content="aaaaaaaa"/>
        <ListViewItem Content="bbbbbbbb"/>
        <ListViewItem Content="cccccccc"/>
        <ListViewItem Content="dddddddd"/>
        <ListViewItem Content="eeeeeeee"/>
        <ListViewItem Content="ffffffff"/>
    </ListView>
    <TextBox Grid.Row="4" Text="Some Footer Text" />
</Grid>


同一网格的行中是否有第二个列表和页脚?否,有两个网格。第一行有三行:页眉、内网格和页脚。内部网格也有三行:复选框、第一个列表框和第二个列表框。因此,每个控件都放在它自己的行中。您已经为两个列表框定义了
MaxHeight
。这不是我想要的结果。如果您要删除
MaxHeight
,则StackPanel将具有网格行的大小,但两个列表都将具有其完整大小,并且第二个列表的底部将位于StackPanel之外,并且没有滚动条。您不应该将ScrollViewer放在StackPanels内。不过这是不必要的。