フォームに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」を選択した場合、カードの詳細を含む行を非表示にします。これを既に非表示にしてフォームを開始することはできません。
グリッド内の行を参照し、行自体の高さを変更することでもこれを行うことができます。
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
グリッド内の要素の折りたたみも機能しますが、折りたたむことができる囲んでいる要素を持たないグリッドに多くのアイテムがある場合、これは少し簡単です。これは良い代替手段を提供します。
行には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>
行または列を折りたたむための最適でクリーンなソリューションは、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>
参考として、Visibility
は3つの状態です System.Windows.Visibility 列挙:
このヒント および WPFのヒントとテクニック スレッドに関するその他のヒントを参照してください。
グリッド行をいじる代わりに、コントロールの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をいくつかのプロパティにバインドできるため、より優れています。
これを行うだけです:rowToHide.Height = new GridLength(0);
uがvisibility.Collapse
を使用する場合、行のすべてのメンバーに設定する必要があります。
行のコンテンツの可視性を非表示ではなく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;