Скрыть строку сетки в WPF - PullRequest
86 голосов
/ 23 марта 2010

У меня есть простая форма 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 ]

73 голосов
/ 19 февраля 2014

Строка не имеет свойства видимости, поэтому, как говорили другие, вам нужно установить высоту. Другой вариант - использовать конвертер, если вам нужна эта функциональность во многих представлениях:

    [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>
63 голосов
/ 13 августа 2015

Лучшее и чистое решение для свертывания строк или столбцов - использовать 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>
51 голосов
/ 27 июня 2010

Вы также можете сделать это, ссылаясь на строку в сетке, а затем изменив высоту самой строки.

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

Хотя свертывание элементов в сетке также работает, это немного проще, если в сетке есть много элементов, в которых нет включающего элемента, который можно свернуть.Это обеспечит хорошую альтернативу.

28 голосов
/ 25 марта 2010

Для справки Visibility - это три состояния System.Windows.Visibility перечисление:

  • Видимый - элемент визуализируется и участвует в макете.
  • Collapsed - элемент невидим и не участвует в макете. Эффективно присваивая ему высоту и ширину 0 и ведя себя так, как будто его не существует.
  • Скрытый - элемент невидим, но продолжает участвовать в макете.

См. этот совет и другие советы по теме Советы и рекомендации WPF .

8 голосов
/ 16 июня 2015

Вместо того, чтобы возиться со строкой сетки, вы можете установить для свойства «Видимость» элементов управления (полей в строке) значение «Свернутый». Это гарантирует, что элементы управления не занимают никакого пространства, и если у вас 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>

Этот метод лучше, потому что видимость элементов управления может быть привязана к некоторому свойству с помощью конвертера.

7 голосов
/ 25 апреля 2012

Просто сделайте это:
rowToHide.Height = new GridLength(0);

если вы будете использовать visibility.Collapse, тогда вам нужно установить его для каждого члена строки.

4 голосов
/ 23 марта 2010

Установите видимость содержимого строки на Visibility.Collapsed вместо Скрытый. Это приведет к тому, что содержимое перестанет занимать место, а строка соответствующим образом уменьшится.

2 голосов
/ 13 мая 2015

У меня была похожая идея, унаследовав 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...