web-dev-qa-db-fra.com

Masquer la ligne de la grille dans WPF

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é.

88
Richard

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.

52
TravisPUK

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>
76
testpattern

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>
64
Lukáš Koten

Pour référence, Visibility est une énumération à trois états System.Windows.Visibility :

  • Visible - L'élément est rendu et participe à la mise en page.
  • Collapsed - L'élément est invisible et ne participe pas à la mise en page. En lui donnant efficacement une hauteur et une largeur de 0 et en se comportant comme si elle n'existait pas.
  • Caché - L'élément est invisible mais continue de participer à la mise en page.

Voir cette astuce et d'autres astuces sur le fil Trucs et astuces WPF .

28
Metro Smurf

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.

8
user3726565

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.

7
USER_NAME

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.

4
Reed Copsey

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;
3
Matt