隐藏WPF中的网格行

我有一个简单的WPF窗体,在窗体上声明一个Grid 。 这个Grid有一堆行:

 <Grid.RowDefinitions> <RowDefinition Height="Auto" MinHeight="30" /> <RowDefinition Height="Auto" Name="rowToHide" /> <RowDefinition Height="Auto" MinHeight="30" /> </Grid.RowDefinitions> 

名为rowToHide的行包含一些input字段,我想在检测到我不需要这些字段后隐藏这一行。 只需将行中的所有项设置为Visibility = Hidden就足够简单,但该行仍占用了Grid空间。 我尝试设置Height = 0的项目,但似乎没有工作。

你可以这样想:你有一个表格,在那里你有一个下拉select“支付types”,如果人select“现金”,你想隐藏包含卡详细信息的行。 已经隐藏起来的forms不是一个选项。

您也可以通过引用网格中的行来更改行的高度。

XAML

 <Grid Grid.Column="2" Grid.Row="1" x:Name="Links"> <Grid.RowDefinitions> <RowDefinition Height="60" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="80" /> </Grid.RowDefinitions> </Grid> 

VB.NET

 If LinksList.Items.Count > 0 Then Links.RowDefinitions(2).Height = New GridLength(1, GridUnitType.Star) Else Links.RowDefinitions(2).Height = New GridLength(0) End If 

虽然网格中元素的折叠也起作用,但是如果网格中有许多项目没有可以折叠的封闭元素,这会更简单一些。 这将提供一个很好的select。

行没有Visibility属性,所以正如其他人所说的那样,您需要设置Height。 另一个select是使用一个转换器,以防万一你在许多视图中需要这个function:

  [ValueConversion(typeof(bool), typeof(GridLength))] public class BoolToGridRowHeightConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return ((bool)value == true) ? new GridLength(1, GridUnitType.Star) : new GridLength(0); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // Don't need any convert back return null; } } 

然后在相应的视图中<Grid.RowDefinition>

 <RowDefinition Height="{Binding IsHiddenRow, Converter={StaticResource BoolToGridRowHeightConverter}}"></RowDefinition> 

折叠行或列的最好和干净的解决scheme是使用一个DataTrigger,所以你的情况:

 <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" MinHeight="30" /> <RowDefinition Name="rowToHide"> <RowDefinition.Style> <Style TargetType="{x:Type RowDefinition}"> <Setter Property="Height" Value="Auto" /> <Style.Triggers> <DataTrigger Binding="{Binding SomeBoolProperty}" Value="True"> <Setter Property="Height" Value="0" /> </DataTrigger> </Style.Triggers> </Style> </RowDefinition.Style> </RowDefinition> <RowDefinition Height="Auto" MinHeight="30" /> </Grid.RowDefinitions> </Grid> 

作为参考, Visibility是一个三态System.Windows.Visibility枚举:

  • 可见 – 元素被渲染并参与布局。
  • 折叠 – 元素不可见,不参与布局。 有效地给它一个高度和宽度为0,并performance得好像它不存在。
  • 隐藏 – 元素不可见,但继续参与布局。

请参阅此提示和WPF提示和技巧线程上的其他提示。

只需做到这一点:
rowToHide.Height = new GridLength(0);

如果你会使用visibility.Collapse那么你必须为每一行的成员设置它。

将行的内容可见Visibility.Collapsed设置为Visibility.Collapsed而不是Hidden。 这会使内容不再占用空间,行会适当缩小。

而不是摆动网格行,您可以将控件的可见性属性(行中的字段)设置为“折叠”。 这将确保控件不占用任何空间,如果您的网格行高=“自动”,则该行将被隐藏,因为该行中的所有控件都具有可见性=“折叠”。

 <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" Name="rowToHide" /> </Grid.RowDefinitions> <Button Grid.Row=0 Content="Click Me" Height="20"> <TextBlock Grid.Row=1 Visibility="{Binding Converter={StaticResource customVisibilityConverter}}" Name="controlToHide"/> </Grid> 

这种方法更好,因为控件的可见性可以通过一个Converter来绑定到一些属性。

我有一个类似的想法inheritanceRowDefinition(仅仅为了兴趣)

 public class MyRowDefinition : RowDefinition { private GridLength _height; public bool IsHidden { get { return (bool)GetValue(IsHiddenProperty); } set { SetValue(IsHiddenProperty, value); } } // Using a DependencyProperty as the backing store for IsHidden. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsHiddenProperty = DependencyProperty.Register("IsHidden", typeof(bool), typeof(MyRowDefinition), new PropertyMetadata(false, Changed)); public static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { var o = d as MyRowDefinition; o.Toggle((bool)e.NewValue); } public void Toggle(bool isHidden) { if (isHidden) { _height = this.Height; this.Height = new GridLength(0, GridUnitType.Star); } else this.Height = _height; } } 

现在你可以使用它如下:

  <Grid.RowDefinitions> <RowDefinition Height="2*" /> <my:MyRowDefinition Height="4*" IsHidden="false" x:Name="RowToHide" /> <RowDefinition Height="*" /> <RowDefinition Height="60" /> </Grid.RowDefinitions> 

并切换

 RowToHide.IsHidden = !RowToHide.IsHidden;