J'ai un formulaire WPF simple avec un Grid
déclaré sur le formulaire. Ce Grid
a un tas de lignes:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="30" />
<RowDefinition Height="Auto" Name="rowToHide" />
<RowDefinition Height="Auto" MinHeight="30" />
</Grid.RowDefinitions>
La ligne nommée rowToHide
contient quelques champs de saisie et je souhaite masquer cette ligne après avoir détecté que je n'ai plus besoin de ces champs. Il est assez simple de simplement définir Visibility = Hidden
Sur tous les éléments de la ligne, mais la ligne occupe toujours de la place dans Grid
. J'ai essayé de définir Height = 0
Sur les éléments, mais cela ne semblait pas fonctionner.
Vous pouvez le penser comme ceci: vous avez un formulaire, vous avez un menu déroulant disant "Type de paiement", et si la personne sélectionne "Argent", vous souhaitez masquer la ligne contenant les détails de la carte. Ce n'est pas une option pour commencer le formulaire avec cela déjà caché.
Vous pouvez également le faire en référençant la ligne dans la grille puis en modifiant la hauteur de la ligne elle-même.
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
Bien que la réduction des éléments dans la grille fonctionne également, cela est un peu plus simple si vous avez plusieurs éléments dans la grille qui ne contiennent pas d'élément englobant qui puisse être réduit. Cela fournirait une bonne alternative.
Row n'a pas de propriété de visibilité. Par conséquent, comme d'autres l'ont dit, vous devez définir la hauteur. Une autre option consiste à utiliser un convertisseur, au cas où vous auriez besoin de cette fonctionnalité dans plusieurs vues:
[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;
}
}
Et puis dans la vue appropriée <Grid.RowDefinition>
:
<RowDefinition Height="{Binding IsHiddenRow, Converter={StaticResource BoolToGridRowHeightConverter}}"></RowDefinition>
La solution la meilleure et la plus propre pour réduire les lignes ou les colonnes consiste à utiliser un DataTrigger de manière à ce que:
<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>
Pour référence, Visibility
est une énumération à trois états System.Windows.Visibility :
Voir cette astuce et d'autres astuces sur le fil Trucs et astuces WPF .
Au lieu de manipuler la ligne de la grille, vous pouvez définir la propriété Visibilité des commandes (champs de la ligne) sur "Réduit". Cela garantira que les contrôles ne prennent pas d'espace et si vous avez Grid Row Height = "Auto", la ligne sera masquée car tous les contrôles de la ligne auront 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>
Cette méthode est préférable car la visibilité des contrôles peut être liée à certaines propriétés à l'aide d'un convertisseur.
Faites simplement ceci:rowToHide.Height = new GridLength(0);
si tu veux utiliser visibility.Collapse
alors vous devez le définir pour chaque membre de la ligne.
Définissez la visibilité du contenu de la ligne sur Visibility.Collapsed
au lieu de Caché. Cela empêchera le contenu de prendre de la place et la ligne sera réduite de manière appropriée.
J'ai eu une idée similaire en héritant de RowDefinition (juste pour l'intérêt)
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;
}
}
Maintenant, vous pouvez l'utiliser comme suit:
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<my:MyRowDefinition Height="4*" IsHidden="false" x:Name="RowToHide" />
<RowDefinition Height="*" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
et basculer avec
RowToHide.IsHidden = !RowToHide.IsHidden;