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आइटम सेट करने की कोशिश की , लेकिन वह काम नहीं कर पाया।

आप इसे इस तरह से सोच सकते हैं: आपके पास एक फॉर्म है, जिसमें आपके पास "भुगतान प्रकार" कहते हुए एक ड्रॉप डाउन है, और यदि व्यक्ति "कैश" का चयन करता है, तो आप कार्ड विवरण वाले पंक्ति को छिपाना चाहते हैं। यह पहले से ही छिपे हुए के साथ फ़ॉर्म को शुरू करने का विकल्प नहीं है।


1
दृश्यता पर इस टिप को देखें 3 राज्य प्रणाली (WPF टिप्स थ्रेड में): stackoverflow.com/questions/860193/wpf-simple-tips-and-tricks/…
मेट्रो स्मर्फ 1

शानदार सामान ... यदि आप इसे एक उत्तर के रूप में डालते हैं तो मैं यह निशान लगाऊंगा कि ...
रिचर्ड

इस टिप को भी देखें: social.msdn.microsoft.com/Forums/en-US/wpf/thread/…
Domokun

जवाबों:


88

पंक्ति में दृश्यता गुण नहीं है, इसलिए जैसा कि अन्य ने कहा है, आपको ऊँचाई निर्धारित करने की आवश्यकता है। एक अन्य विकल्प एक कनवर्टर का उपयोग करना है, कई मामलों में आपको इस कार्यक्षमता की आवश्यकता होती है:

    [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 में घोषित होने के लिए यह सब अनुमति देते हैं। मैं आम तौर पर दृश्य सामग्री के साथ फिडल करने के लिए कोड-पीछे का उपयोग करके नफरत करता हूं।
एलन

1
यह बहुत उपयोगी है और आसानी से बढ़ाया जा सकता है। मेरा सुझाव है कि इसे कॉल करें BoolToGridLengthConverterऔर VisibleLengthवापस आने के लिए -Property को जोड़ें (bool)value == true। Thats कैसे आप इसे Autoऔर किसी भी फिक्स-मूल्य के साथ पुन: उपयोग कर सकते हैं
लकीलीकी

1
बहुत बढ़िया जवाब। मुझे लगता है कि आप IsDisplayedRow का मतलब है, IsHiddenRow नहीं।
एनआईएलडब्ल्यू

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यह बदल जाए तो काम करने के लिए अपने कोड को लागू करना न भूलें :)।
बेनिक्का

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

जबकि ग्रिड के भीतर तत्वों का कोलैप्सिंग भी काम करता है, यह थोड़ा सरल है यदि आपके पास ग्रिड में कई आइटम हैं जिसमें एक संलग्नक तत्व नहीं है जो ढह सकता है। यह एक अच्छा विकल्प प्रदान करेगा।


2
यह उन पंक्तियों के साथ काम करने का भी लाभ है जो स्टार नोटेशन का उपयोग करता है!
जॉनी स्कोवडाल

1
कोड में ऐसा करना सबसे स्पष्ट, सबसे पठनीय समाधान है। शायद के बाद एक टिप्पणी जोड़ें RowDefinition, जैसे<RowDefinition Height="*" /><!-- Height set in code behind -->
Kay Zed

2
मुझे नहीं लगता कि कार्यात्मक कोड दो अलग-अलग फ़ाइलों में विभाजित होने के बाद यह सबसे स्पष्ट और सबसे पठनीय समाधान है। वास्तव में यह सब शुद्ध एक्सएएमएल के साथ किया जा सकता है - मेरा जवाब देखें।
लुकास कोटेन

मेरी ज़रूरतें थोड़ी अलग थीं और सी # में लेकिन इस उदाहरण ने मुझे सही दिशा में ला दिया। धन्यवाद!
nrod

30

संदर्भ के लिए, Visibilityएक तीन-राज्य प्रणाली है। Windows.Visibility गणन:

  • दर्शनीय - तत्व का प्रतिपादन और लेआउट में भाग लेता है।
  • ढह गया - तत्व अदृश्य है और लेआउट में भाग नहीं लेता है। प्रभावी रूप से इसे 0 की ऊंचाई और चौड़ाई देना और ऐसा व्यवहार करना जैसे कि यह मौजूद नहीं है।
  • छिपी - तत्व अदृश्य है लेकिन लेआउट में भाग लेना जारी रखता है।

WPF टिप्स और ट्रिक्स धागे पर इस टिप और अन्य सुझावों को देखें ।


1
रो में सभी आइटम को विजिबिलिटी पर सेट करना।
रिचर्ड

1
मैंने इसे अस्वीकार कर दिया क्योंकि मुझे लगता है कि @ ट्रैविसपुक के उत्तर में एक स्पष्ट, अधिक स्पष्ट समाधान शामिल है।
टेस्टाप्टर्न

11
@testpattern - डाउनवोट्स का उपयोग आमतौर पर गलत उत्तरों के लिए किया जाता है। यदि अन्य उत्तर बेहतर है, तो इसे बढ़ाएं।
मेट्रो स्मर्फ

6
@MetroSmurf मेला काफी तर्क से, आपका उत्तर सही नहीं है क्योंकि रोवडिफिनेशन में विजिबिलिटी के लिए प्रॉपर्टी नहीं है। ट्रैविसपुक दिखाता है कि एक पंक्ति को कैसे छिपाया जाए और यह स्वीकृत उत्तर होना चाहिए।
टेस्टपैटर्न

8

ग्रिड रो के साथ फ़िडलिंग करने के बजाय, आप नियंत्रण की दृश्यता गुण (पंक्ति में फ़ील्ड) "कोलैप्स" कर सकते हैं। यह सुनिश्चित करेगा कि नियंत्रण कोई स्थान नहीं लेता है और यदि आपके पास ग्रिड रो ऊँचाई = "ऑटो" है, तो पंक्ति छिपाई जाएगी क्योंकि पंक्ति के सभी नियंत्रणों में दृश्यता = "संकुचित" है।

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

यदि आप यू का उपयोग करेंगे visibility.Collapseतो यू को इसे पंक्ति के प्रत्येक सदस्य के लिए सेट करना होगा।


6

Visibility.Collapsedछिपे के बजाय पंक्ति की सामग्री दृश्यता सेट करें । इससे सामग्री को जगह लेना बंद हो जाएगा, और पंक्ति उचित रूप से सिकुड़ जाएगी।


1
मैंने देखा है किसी और ने रो विज़िबिलिटी का उल्लेख किया है। लेकिन पंक्ति में दृश्यता की स्थिति नहीं होती है? पंक्ति में सभी आइटम को दृश्यता पर सेट करना।
रिचर्ड

5
@ रीचर्ड: आप पंक्तिबद्धता को सेट नहीं कर सकते। क्योंकि यह एक UIElement नहीं है - लेकिन आप एक पंक्ति में पंक्ति (या पंक्ति के भीतर प्रत्येक स्तंभ) के लिए अपनी सामग्री डाल सकते हैं, और उस कंटेनर की चिपचिपाहट सेट कर सकते हैं।
रीड कोपसे

1
क्या होगा यदि आपकी ग्रिड पंक्ति में कोई सामग्री नहीं है, लेकिन एक निश्चित ऊंचाई है? क्या दिखाने / छिपाने का एक सुविधाजनक तरीका है?
केविनरपे

4

मुझे रोवेफिनिशन (सिर्फ ब्याज के लिए) विरासत में मिला था।

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;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.