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内。不过这是不必要的。