web-dev-qa-db-ja.com

WPFでグリッド行を非表示

フォームにGridが宣言された単純なWPFフォームがあります。この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をアイテムに設定しようとしましたが、うまくいかないようです。

次のように考えることができます。フォームがあり、そこに「Payment Type」というドロップダウンがあり、その人が「Cash」を選択した場合、カードの詳細を含む行を非表示にします。これを既に非表示にしてフォームを開始することはできません。

88
Richard

グリッド内の行を参照し、行自体の高さを変更することでもこれを行うことができます。

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

グリッド内の要素の折りたたみも機能しますが、折りたたむことができる囲んでいる要素を持たないグリッドに多くのアイテムがある場合、これは少し簡単です。これは良い代替手段を提供します。

52
TravisPUK

行にはVisibilityプロパティがないため、他の人が言ったように、Heightを設定する必要があります。別のオプションは、多くのビューでこの機能が必要な場合にコンバーターを使用することです。

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

行または列を折りたたむための最適でクリーンなソリューションは、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>
64
Lukáš Koten

参考として、Visibilityは3つの状態です System.Windows.Visibility 列挙:

  • 表示-要素がレンダリングされ、レイアウトに参加します。
  • Collapsed-要素は非表示であり、レイアウトに参加しません。効果的に0の高さと幅を与え、存在しないかのように動作します。
  • 非表示-要素は表示されませんが、レイアウトに参加し続けます。

このヒント および WPFのヒントとテクニック スレッドに関するその他のヒントを参照してください。

28
Metro Smurf

グリッド行をいじる代わりに、コントロールのVisibilityプロパティ(行のフィールド)を「折りたたみ」に設定できます。これにより、コントロールがスペースを占有せず、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>

この方法は、Converterを使用してコントロールのVisibilityをいくつかのプロパティにバインドできるため、より優れています。

8
user3726565

これを行うだけです:
rowToHide.Height = new GridLength(0);

uがvisibility.Collapseを使用する場合、行のすべてのメンバーに設定する必要があります。

7
USER_NAME

行のコンテンツの可視性を非表示ではなくVisibility.Collapsedに設定します。これにより、コンテンツがスペースを占有しなくなり、行が適切に縮小されます。

4
Reed Copsey

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