Скрыть строку сетки в 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
к предметам, но это, похоже, не сработало.
вы можете думать об этом так: у вас есть форма, там у вас есть выпадающее меню с надписью "тип платежа", и если человек выбирает "наличные", вы хотите скрыть строку, содержащую данные карты. Это не вариант, чтобы начать форму с этой скрытой уже.
8 ответов:
вы также можете сделать это, обратившись к строке в сетке, а затем изменив высоту самой строки.
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
в то время как сворачивание элементов в сетке также работает, это немного проще, если у вас есть много элементов в сетке, которая не имеет заключающего элемента, который может быть свернут. Это было бы хорошей альтернативой.
строка не имеет свойства видимости, так как другие сказали, что вам нужно установить высоту. Другой вариант - использовать конвертер, если вам нужна эта функция во многих представлениях:
[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>
лучшим и чистым решением для сворачивания строк или столбцов является использование 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>
просто сделать это:
rowToHide.Height = new GridLength(0);
Если u будет использовать
visibility.Collapse
тогда вы должны установить его для каждого члена строки.
вместо того, чтобы возиться со строкой сетки, вы можете установить свойство видимости элементов управления (полей в строке) в "свернуто". Это гарантирует, что элементы управления не занимают никакого места, и если у вас есть высота строки сетки="авто", то строка будет скрыта, поскольку все элементы управления в строке имеют видимость="свернуто".
<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>
этот метод лучше, потому что видимость элементов управления может быть привязана к некоторому свойству с помощью преобразователя.
установите видимость содержимого строки в
Visibility.Collapsed
вместо скрыта. Это заставит содержимое перестать занимать место, и строка будет сжиматься соответствующим образом.
у меня была аналогичная идея, унаследовав 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;