WPF에서 그리드 행 숨기기


94

양식에 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"를 선택하면 카드 세부 정보가 포함 된 행을 숨기고 싶습니다. 이미 숨겨진 상태로 양식을 시작하는 것은 옵션이 아닙니다.


1
3 상태 시스템 인 가시성에 대한이 팁을 참조하십시오 (WPF 팁 스레드에서) : stackoverflow.com/questions/860193/wpf-simple-tips-and-tricks/…
Metro Smurf

당신이 대답으로 그것을 내려 놓고 싶다면 화려한 물건 ... 난 ... 그 표시 줄
리처드

답변:


88

행에는 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>

10
UpVoted-변환기는이 모든 것을 Xaml에서 선언적으로 허용합니다. 나는 일반적으로 시각적 인 것들을 조작하기 위해 코드 숨김을 사용하는 것을 싫어합니다.
Allen

1
이것은 매우 유용하며 쉽게 확장 할 수 있습니다. 나는 그것을 호출 BoolToGridLengthConverter하고 VisibleLength-Property를 추가하여 (bool)value == true. 그것이 당신이 그것을 또한 Auto수정 값과 함께 재사용 할 수있는 방법 입니다.
LuckyLikey

1
좋은 대답입니다. IsHiddenRow가 아니라 IsDisplayedRow를 의미한다고 가정합니다.
NielW

72

행이나 열을 축소하는 가장 좋고 깨끗한 솔루션은 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>

5
추가 C # 코드가 필요하지 않기 때문에이 방법을 좋아합니다.
user11909

1
가 변경 INotifyPropertyChanged될 때 작동하도록 코드 뒤에서 구현하는 것을 잊지 마십시오 SomeBoolProperty. :).
benichka

55

그리드의 행을 참조한 다음 행 자체의 높이를 변경하여이를 수행 할 수도 있습니다.

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

Grid 내의 요소 축소도 작동하지만 축소 할 수있는 둘러싸는 요소가없는 Grid에 많은 항목이있는 경우 이것은 조금 더 간단합니다. 이것은 좋은 대안을 제공 할 것입니다.


2
이것은 또한 별표 표기법을 사용하는 행으로 작업하는 이점이 있습니다!
Johny는 Skovdal

1
코드에서이 작업을 수행하는 것이 가장 명확하고 가장 읽기 쉬운 솔루션입니다. 아마도 후 댓글을 추가 RowDefinition처럼<RowDefinition Height="*" /><!-- Height set in code behind -->
케이 데이빗

2
기능 코드가 두 개의 개별 파일로 나뉘어져 있기 때문에 이것이 가장 명확하고 가장 읽기 쉬운 솔루션이라고 생각하지 않습니다. 사실 순수한 XAML로 모든 작업을 수행 할 수 있습니다. 내 대답을 참조하십시오.
Lukáš Koten

내 요구 사항은 C #에서 약간 달랐지만이 예제는 올바른 방향을 제시했습니다. 감사!
nrod

30

참고로 다음 Visibility은 세 가지 상태의 System.Windows.Visibility 열거 형입니다.

  • Visible-요소가 렌더링되고 레이아웃에 참여합니다.
  • 축소됨-요소가 보이지 않으며 레이아웃에 참여하지 않습니다. 효과적으로 높이와 너비를 0으로 지정하고 존재하지 않는 것처럼 작동합니다.
  • 숨김-요소가 보이지 않지만 레이아웃에 계속 참여합니다.

이 팁WPF 팁 및 트릭 스레드 에 대한 기타 팁을 참조하십시오 .


1
행의 모든 ​​항목을 Visibility.Collapsed로 설정했습니다. 감사합니다.
Richard

1
@TravisPUK의 답변에 더 명확하고 분명한 해결책이 포함되어 있다고 생각하기 때문에 나는 이것을 반대 투표했습니다.
testpattern

11
@testpattern-비추천은 일반적으로 오답에 사용됩니다. 다른 답변이 더 낫다면 찬성 투표하세요.
Metro Smurf

6
@MetroSmurf 충분히 공정합니다. 틀림없이 RowDefinition에는 Visibility에 대한 속성이 없기 때문에 답변이 올바르지 않습니다. TravisPUK는 행을 숨기는 방법을 보여 주며, 이것이 허용되는 대답이어야합니다.
testpattern 2014

8

Grid Row를 조작하는 대신 컨트롤 (행의 필드)의 Visibility 속성을 "Collapsed"로 설정할 수 있습니다. 이렇게하면 컨트롤이 공간을 차지하지 않고 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>

이 방법은 변환기의 도움으로 컨트롤의 가시성을 일부 속성에 바인딩 할 수 있기 때문에 더 좋습니다.


7

다음과 같이하십시오.
rowToHide.Height = new GridLength(0);

u를 사용할 경우 visibility.Collapse행의 모든 ​​구성원에 대해 설정해야합니다.


6

행의 컨텐츠 가시성을 Visibility.Collapsed숨김 대신으로 설정하십시오 . 이렇게하면 콘텐츠가 공간을 차지하지 않고 행이 적절하게 축소됩니다.


1
다른 곳에서 누군가 행 가시성에 대해 언급 한 것을 보았습니다. 그러나 행에는 가시성 상태가 없습니까? 행의 모든 ​​항목을 Visibility.Collapsed로 설정하면 작동했습니다.
리처드

5
@Richard : UIElement가 아니기 때문에 RowDefinition.Visibility를 설정할 수는 없지만 행 (또는 행 내의 각 열)에 대한 모든 콘텐츠를 단일 컨테이너에 넣고 해당 컨테이너의 가시성을 설정할 수 있습니다.
Reed Copsey

1
그리드 행에 내용이 없지만 높이가 고정되어 있다면 어떨까요? 표시 / 숨기기 편리한 방법이 있습니까?
kevinarpe

4

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;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.