Скрыть строку сетки в WPF
У меня есть простая форма 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
на элементы, но это, похоже, не сработало.
Вы можете думать об этом так: у вас есть форма, там вы видите "Тип платежа", и если человек выбирает "Наличные деньги", вы хотите скрыть строку, содержащую данные Карты. Невозможно запустить форму с этим уже скрытым.
Ответы
Ответ 1
Вы также можете сделать это, указав строку в сетке, а затем изменив высоту самой строки.
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
В то время как слияние элементов внутри Grid также работает, это немного проще, если в Grid есть много элементов, которые не имеют закрывающего элемента, который может быть свернут. Это будет хорошей альтернативой.
Ответ 2
Строка не имеет свойства Видимость, так как другие сказали, вам нужно установить высоту. Другой вариант - использовать конвертер, если вам нужна эта функция во многих представлениях:
[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>
Ответ 3
Лучшим и чистым решением для свертывания строк или столбцов является использование 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>
Ответ 4
Для справки Visibility
представляет собой трехступенчатое System.Windows.Visibility перечисление:
- Видимый - элемент получает визуализацию и участвует в компоновке.
- Свернуто - элемент невидим и не участвует в макете. Эффективно давая ему высоту и ширину 0 и ведя себя так, как будто этого не существует.
- Скрытый - элемент невидим, но продолжает участвовать в макете.
Смотрите этот совет и другие советы в WPF Tips and Tricks.
Ответ 5
Просто выполните следующее:
rowToHide.Height = new GridLength(0);
если u будет использовать visibility.Collapse
, тогда u должен установить его для каждого члена строки.
Ответ 6
Установите видимость содержимого строки в Visibility.Collapsed
вместо скрытого. Это приведет к тому, что содержимое перестанет занимать место, а строка будет уменьшаться соответствующим образом.
Ответ 7
Вместо того, чтобы возиться с 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>
Этот метод лучше, потому что видимость элементов управления может быть привязана к некоторому свойству с помощью конвертера.
Ответ 8
У меня была аналогичная идея, наследуя 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;