WPF'de ızgara satırını gizle


96

Formda Gridbeyan edilen basit bir WPF formum var . Bu Gridsatırların bir grup var:

<Grid.RowDefinitions>
    <RowDefinition Height="Auto" MinHeight="30" />
    <RowDefinition Height="Auto" Name="rowToHide" />
    <RowDefinition Height="Auto" MinHeight="30" />
</Grid.RowDefinitions>

Adlı satır rowToHidebirkaç giriş alanı içeriyor ve bu alanlara ihtiyacım olmadığını belirledikten sonra bu satırı gizlemek istiyorum. Visibility = HiddenSatırdaki tüm öğelere ayarlamak yeterince basit , ancak satır yine de Grid. Height = 0Öğeleri ayarlamayı denedim , ama bu işe yaramadı.

Şöyle düşünebilirsiniz: Bir formunuz var, orada "Ödeme Tipi" yazan bir açılır menü var ve kişi "Nakit" i seçerse, Kart ayrıntılarını içeren satırı gizlemek istersiniz. Formu bu gizli olarak başlatmak bir seçenek değildir.


1
Görünürlük 3 durumlu bir sistem olan bu ipucuna bakın (WPF ipuçları başlığında): stackoverflow.com/questions/860193/wpf-simple-tips-and-tricks/…
Metro Smurf

Harika şeyler ... Cevap olarak yazarsan, bunu işaretlerim ...
Richard

Yanıtlar:


89

Row'un Görünürlük özelliği yoktur, bu nedenle diğerlerinin de söylediği gibi, Yüksekliği ayarlamanız gerekir. Diğer bir seçenek, birçok görünümde bu işleve ihtiyaç duymanız durumunda bir dönüştürücü kullanmaktır:

    [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;
        }
    }

Ve sonra uygun görünümde <Grid.RowDefinition>:

<RowDefinition Height="{Binding IsHiddenRow, Converter={StaticResource BoolToGridRowHeightConverter}}"></RowDefinition>

10
UpVoted - Dönüştürücüler, tüm bunların Xaml'de bildirime dayalı olmasına izin verir. Genelde görsel şeylerle uğraşmak için arka planda kod kullanmaktan nefret ederim.
Allen

1
Bu oldukça kullanışlıdır ve kolaylıkla genişletilebilir. Geri dönmek için onu çağırmanızı BoolToGridLengthConverterve bir VisibleLength-Özellik eklemenizi öneririm (bool)value == true. Bu, onu Autove herhangi bir düzeltme değeri ile yeniden kullanmanın yolu .
LuckyLikey

1
Mükemmel cevap. IsDisplayedRow demek istediğini varsayıyorum, IsHiddenRow değil.
NielW

73

Satırları veya sütunları daraltmanın en iyi ve temiz çözümü, sizin durumunuzda bir DataTrigger kullanmaktır:

<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
Bu yaklaşımı seviyorum çünkü ek C # koduna ihtiyacınız yok.
user11909

1
Değiştirildiğinde INotifyPropertyChangedçalışması için arkasındaki kodunuza eklemeyi unutmayın SomeBoolProperty:).
benichka

55

Bunu ayrıca Izgaradaki Satırı referans alarak ve ardından satırın Yüksekliğini değiştirerek de yapabilirsiniz.

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

Izgara içindeki öğelerin Daraltılması da işe yarasa da, Izgarada daraltılabilen çevreleyen bir öğeye sahip olmayan birçok öğeniz varsa bu biraz daha basittir. Bu, iyi bir alternatif sağlayacaktır.


2
Bu aynı zamanda yıldız gösterimini kullanan satırlarla çalışma avantajına da sahiptir!
Johny Skovdal

1
Bunu kodla yapmak en net, en okunabilir çözümdür. Belki sonra Yorum eklemek RowDefinitiongibi<RowDefinition Height="*" /><!-- Height set in code behind -->
Kay Zed

2
İşlevsel kod iki ayrı dosyaya bölündüğü için bunun en net ve en okunabilir çözüm olduğunu düşünmüyorum. Aslında bunların hepsi saf XAML ile yapılabilir - cevabıma bakın.
Lukáš Koten

İhtiyaçlarım biraz farklıydı ve C # 'da ama bu örnek beni doğru yönde gösterdi. Teşekkürler!
nrod

30

Başvuru için, Visibilityüç durumlu bir System.Windows.Visibility numaralandırmasıdır:

  • Görünür - Öğe oluşturulur ve düzene katılır.
  • Daraltılmış - Öğe görünmezdir ve düzene katılmaz. Etkili bir şekilde 0 yükseklik ve genişlik verir ve yokmuş gibi davranır.
  • Gizli - Öğe görünmez, ancak düzene katılmaya devam ediyor.

Bu ipucuna ve WPF İpuçları ve Püf Noktaları başlığındaki diğer ipuçlarına bakın .


1
Satırdaki tüm Öğeleri Görünürlük'e Ayarlama Harmanlanmış çalıştı, teşekkürler.
Richard

1
Buna olumsuz oy verdim çünkü @ TravisPUK'un cevabının daha net ve daha açık bir çözüm içerdiğini düşünüyorum.
testpattern

11
@testpattern - olumsuz oylar genellikle yanlış yanıtlar için kullanılır. Diğer cevap daha iyiyse, oy verin.
Metro Smurf

6
@MetroSmurf yeterince adil. Muhtemelen cevabınız doğru değil çünkü RowDefinition'ın Görünürlük için bir özelliği yok. TravisPUK bir satırın nasıl gizleneceğini gösteriyor ve bu kabul edilen cevap olmalı.
testpattern

8

Izgara Satırı ile uğraşmak yerine, Kontrollerin Görünürlük özelliğini (satırdaki alanlar) "Daraltılmış" olarak ayarlayabilirsiniz. Bu, kontrollerin herhangi bir yer kaplamamasını sağlar ve Grid Row Height = "Auto" değerine sahipseniz, satırdaki tüm kontrollerin Visibility = "Collapsed" olması nedeniyle satır gizlenecektir.

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

Bu yöntem daha iyidir, çünkü kontrollerin Görünürlüğü bir Dönüştürücü yardımıyla bazı özelliklere bağlanabilir.


7

Basitçe şunu yapın:
rowToHide.Height = new GridLength(0);

u kullanacaksanız, visibility.Collapseu satırın her üyesi için ayarlamanız gerekir.


6

Satırın içerik görünürlüğünü Visibility.CollapsedGizli yerine olarak ayarlayın . Bu, içeriğin yer kaplamasını durduracak ve satır uygun şekilde küçülecektir.


1
Başka bir yerde birinin Satır Görünürlüğünden bahsettiğini gördüm. Ancak Row'un görünürlük durumu yok mu? Satırdaki tüm Öğeleri Görünürlük olarak Ayarlama. Harmanlanmış yine de işe yaradı.
Richard

5
@Richard: RowDefinition.Visibility değerini bir UIElement olmadığı için ayarlayamazsınız - ancak satıra (veya satırdaki her bir sütuna) ilişkin tüm içeriğinizi tek bir kaba koyabilir ve bu kapsayıcının görünürlüğünü ayarlayabilirsiniz.
Reed Copsey

1
Ya ızgara satırınızda herhangi bir içerik yoksa, ancak sabit bir yükseklik varsa? Göstermenin / gizlemenin uygun bir yolu var mı?
kevinarpe

4

RowDefinition'ı miras alarak benzer bir fikrim vardı (sadece ilgi için)

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;
    }          
}

Şimdi aşağıdaki gibi kullanabilirsiniz:

 <Grid.RowDefinitions>
        <RowDefinition Height="2*" />
        <my:MyRowDefinition Height="4*" IsHidden="false" x:Name="RowToHide" />
        <RowDefinition Height="*" />
        <RowDefinition Height="60" />
    </Grid.RowDefinitions>

ve ile geçiş yapın

RowToHide.IsHidden = !RowToHide.IsHidden;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.