首页 文章

隐藏WPF中的网格行

提问于
浏览
84

我有一个简单的WPF表单,表单上声明了 Grid . 这 Grid 有一堆行:

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

名为 rowToHide 的行包含一些输入字段,我想在检测到之后隐藏此行,我只需将 Visibility = Hidden 设置为行中的所有项目,但该行仍占用 Grid 中的空间 . 我尝试将 Height = 0 设置为项目,但这似乎不起作用 .

你可以这样想:你有一个表格,在那里你有一个下拉说“付款类型”,如果这个人选择“现金”,你想要隐藏包含卡详细信息的行 . 这个隐藏的表单不是一个选项 .

8 回答

  • 28

    您也可以通过引用网格中的行然后更改行本身的高度来执行此操作 .

    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
    

    虽然网格中元素的折叠也有效,但如果网格中有许多项目没有可折叠的封闭元素,则会更简单一些 . 这将提供一个很好的选择 .

  • 2

    Row没有Visibility属性,正如其他人所说,你需要设置高度 . 另一种选择是使用转换器,以防您在许多视图中需要此功能:

    [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>
    
  • 7

    折叠行或列的最佳和干净的解决方案是使用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>
    
  • 70

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

    • 可见 - 元素被渲染并参与布局 .

    • Collapsed - 元素不可见,不参与布局 . 有效地给它一个0的高度和宽度,并表现得好像它不存在 .

    • 隐藏 - 元素不可见但继续参与布局 .

    请参阅this tip以及WPF Tips and Tricks线程上的其他提示 .

  • 62

    只需这样做:
    rowToHide.Height = new GridLength(0);

    如果你将使用 visibility.Collapse 那么你必须为该行的每个成员设置它 .

  • 7

    您可以将Controls的Visibility属性(行中的字段)设置为“Collapsed”,而不是摆弄Grid Row . 这将确保控件不占用任何空间,如果您有Grid Row Height =“Auto”,则该行将被隐藏,因为该行中的所有控件都具有Visibility =“Collapsed” .

    <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的帮助下绑定到某些属性 .

  • 51

    将行的内容可见性设置为 Visibility.Collapsed 而不是隐藏 . 这将使内容停止占用空间,并且行将适当缩小 .

  • 4

    我有一个类似的想法,继承RowDefinition(只是为了兴趣)

    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;
    

相关问题