WPF में GridViewColumn डेटा को ऑटोसाइज़ और राइट-एलाइन कैसे करें?


89

मैं कैसे कर सकता हूँ:

  • ID कॉलम में टेक्स्ट को राइट-अलाइन करें
  • सेल के प्रत्येक कॉलम को सबसे लंबे समय तक दिखाई देने वाले डेटा के साथ टेक्स्ट की लंबाई के अनुसार ऑटो आकार दें?

यहाँ कोड है:

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="40"/>
            <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="100" />
            <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
        </GridView>
    </ListView.View>
</ListView>

आंशिक उत्तर:

धन्यवाद Kjetil, GridViewColumn.CellTemplate अच्छी तरह से और ऑटो चौड़ाई के काम करता है, लेकिन जब ऑब्जर्वेटिवकोलिलेशन "संग्रह" को लंबे-से-स्तंभ-चौड़ाई के डेटा के साथ अपडेट किया जाता है, तो कॉलम आकार खुद को अपडेट नहीं करते हैं, जो केवल समाधान के लिए एक समाधान है डेटा का प्रारंभिक प्रदर्शन:

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="ID" Width="Auto">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Id}" TextAlignment="Right" Width="40"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
            <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
        </GridView>
    </ListView.View>
</ListView>

1
क्या आपको कभी अपने ऑटो-साइज़ की समस्या का हल मिला? मैं एक ही चीज का अनुभव कर रहा हूं।
Oskar

2
@ ऑस्कर - सूची का वर्चुअलाइजेशन एक ऑटो-समाधान को रोकता है। सूची केवल वर्तमान में दिखाई देने वाली वस्तुओं के बारे में जानती है और तदनुसार आकार निर्धारित करती है। यदि सूची के नीचे और आइटम हैं, तो यह उनके बारे में नहीं जानता है और इसलिए उनके लिए कोई खाता नहीं है। यदि आप डेटा बाइंडिंग का उपयोग कर रहे हैं तो ProgrammingWPF - Sells-Griffith पुस्तक मैन्युअल कॉलम चौड़ाई की सिफारिश करती है। :(
गिशु

@ जीशु धन्यवाद, जो वास्तव में समझ में आता है ..
Oskar

यदि MVVM और बाइंडिंग मानों का उपयोग बदल रहा है, तो कृपया @Rolf Wessels उत्तर देखें।
जेक बर्गर

जवाबों:


104

प्रत्येक कॉलम को स्वत: आकार देने के लिए आप GridViewColumn पर Width = "Auto" सेट कर सकते हैं।

आईडी कॉलम में टेक्स्ट को राइट-अलाइन करने के लिए आप टेक्स्टब्लॉक का उपयोग करके एक सेल टेम्प्लेट बना सकते हैं और टेक्स्टअलाइनमेंट सेट कर सकते हैं। फिर संपूर्ण GridViewCell को भरने के लिए सेल टेम्पलेट बनाने के लिए ListViewItem.Hor क्षैतिजContentAlignment (ListViewItem पर एक सेटर के साथ शैली का उपयोग करके) सेट करें।

शायद एक सरल उपाय है, लेकिन यह काम करना चाहिए।

नोट: समाधान के लिए दोनों क्षैतिज क्षैतिज वर्गीकरण = खिड़की में खिंचाव की आवश्यकता है । स्रोत और TextAlignment = CellTemplate में सही

<Window x:Class="WpfApplication6.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
    <Style TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</Window.Resources>
<Grid>
    <ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="ID" Width="40">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Id}" TextAlignment="Right" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
                <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>
</Window>

@Kjetil - क्या मैं इस सेटिंग को एक विशिष्ट कॉलम पर लागू कर सकता हूं?
गिशु

15
+1 के लिए: <सेटर प्रॉपर्टी = "हॉरिज़ॉन्टल कॉन्टेंट ऑलिगमेंट" वैल्यू = "स्ट्रेच" />
हेल्स क्लेन

कमाल है, लेकिन मेरे पास 15 कॉलम हैं, क्या मुझे किसी भी तरह से उन सभी के लिए सेलटेमप्लेट दोहराना नहीं है?
नितिन चौधरी

7
यदि आप GridViewColumn से DisplayMemberBinding को हटाना भूल जाते हैं तो यह भी काम नहीं करता है। तब टेम्पलेट का कोई प्रभाव नहीं होगा।
floele

@ मोहम्मद यह क्यों नहीं है?
इट्नोटली।

36

यदि सामग्री की चौड़ाई बदलती है, तो आपको प्रत्येक कॉलम को अपडेट करने के लिए इस बिट कोड का उपयोग करना होगा:

private void ResizeGridViewColumn(GridViewColumn column)
{
    if (double.IsNaN(column.Width))
    {
        column.Width = column.ActualWidth;
    }

    column.Width = double.NaN;
}

आपको उस कॉलम के अपडेट के लिए हर बार इसे फायर करना होगा।


1
आप इसे किससे जोड़ेंगे?
आर्किटेज

1
ग्रिड डेटा अपडेट करने के बाद इसे ग्रिड व्यू पर मैन्युअल रूप से चलाएं। यदि आपको एक ViewModel मिला है, तो आप उस पर PropertyChanged ईवेंट की सदस्यता ले सकते हैं और फिर उसे चला सकते हैं।
रैंडम एनी

इसके लिए +1 धन्यवाद! इसने मेरी बहुत मदद की! इस प्रश्न से संबंधित नहीं है, लेकिन फिर भी: मैंने एक अनुकूलित सूची / ग्रिड दृश्य लागू किया है जहां आप GUI के माध्यम से रनटाइम पर कॉलम को गतिशील रूप से जोड़ / हटा सकते हैं। हालाँकि, जब मैंने एक कॉलम को हटाया और पुनः जोड़ा, तो यह अब दिखाई नहीं दिया। सबसे पहले, मुझे लगा कि यह (किसी कारण के लिए) बिल्कुल नहीं जोड़ा गया था, लेकिन तब (स्नूप का उपयोग करके) मुझे पता चला कि यह वास्तव में जोड़ा गया है, लेकिन इसमें एक्चुअलविद का 0 है (यह ऑटो-आकार और जाहिर है रीसेट किया गया था जब स्तंभ था हटा दिया)। कॉलम में पुन: जोड़ने के बाद, मैं कॉलम को सही चौड़ाई में सेट करने के लिए आपके कोड का उपयोग करता हूं। बहुत धन्यवाद!
गेहूँ 24'10

मेरी समस्या का एक सरल समाधान!
गक्क्निबग

+1 परफेक्ट! काश यह जवाब के रूप में चिह्नित किया गया था। मैंने xAML में x: Name = "gvcMyColumnName" जोड़ा जहां कॉलम को परिभाषित किया गया था ताकि मैं इसे पीछे के कोड में एक्सेस कर सकूं। चंवर की तरह काम करता है।
K0D4

19

यदि आपकी सूची भी फिर से आकार दे रही है, तो आप पूर्ण ListView चौड़ाई को फिट करने के लिए स्तंभों को फिर से आकार देने के लिए एक व्यवहार पैटर्न का उपयोग कर सकते हैं। लगभग आप ग्रिड का उपयोग कर के रूप में ही। परिभाषाएँ

<ListView HorizontalAlignment="Stretch"
          Behaviours:GridViewColumnResize.Enabled="True">
        <ListViewItem></ListViewItem>
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Column *"
                                   Behaviours:GridViewColumnResize.Width="*" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox HorizontalAlignment="Stretch" Text="Example1" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>

कुछ उदाहरणों के लिए निम्न लिंक देखें और स्रोत कोड से लिंक करें http://lazycowprojects.tumblr.com/post/7063214400/wpf-c-listview-column-width-auto


यह एक शांत है। समस्या को हल करता है और आपको सभी एन , एन , ऑटो कार्यक्षमता प्रदान करता है जो आप देख रहे हैं।
डिजाइनपैटर्न

यह वही है जिसे मैं देख रहा था। : डी
जेक बर्गर

नोट: एक बग लगता है। जब सूची दृश्य को लंबवत आकार दिया जाता है, तो उस बिंदु पर जो एक ऊर्ध्वाधर स्क्रॉलबार दिखाई देता है, स्तंभ लगातार चौड़ाई में बढ़ेगा जब तक स्क्रॉलबार गायब नहीं हो जाता।
जेक बर्गर

1
यह पोस्ट मेरी पिछली टिप्पणी में वर्णित व्यवहार पर अंतर्दृष्टि प्रदान कर सकती है।
जेक बर्गर

यह अच्छा है, मेरा मतलब है कि कोड और साइट दोनों :)। मेरा मानना ​​है कि यह तब उपयोगी होगा जब मेरे पास सख्त आवश्यकताएं होंगी।
गक्क्निबग

12

मैंने निम्नलिखित वर्ग को बनाया है और इसके स्थान पर जहाँ भी आवश्यक हो प्रयोग किया जाता है GridView:

/// <summary>
/// Represents a view mode that displays data items in columns for a System.Windows.Controls.ListView control with auto sized columns based on the column content     
/// </summary>
public class AutoSizedGridView : GridView
{        
    protected override void PrepareItem(ListViewItem item)
    {
        foreach (GridViewColumn column in Columns)
        {
            // Setting NaN for the column width automatically determines the required
            // width enough to hold the content completely.

            // If the width is NaN, first set it to ActualWidth temporarily.
            if (double.IsNaN(column.Width))
              column.Width = column.ActualWidth;

            // Finally, set the column with to NaN. This raises the property change
            // event and re computes the width.
            column.Width = double.NaN;              
        }            
        base.PrepareItem(item);
    }
}

7

चूँकि मेरे पास ItemContainerStyle था, इसलिए मुझे ItemContainerStyle में HoroscopeContentAlignment डालना था।

    <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=FieldDef.DispDetail, Mode=OneWay}" Value="False">
                         <Setter Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </Style.Triggers>
                <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
    ....

6

मुझे उपयोगकर्ता के पसंद आया1313423 का समाधान, सिवाय इसके कि यह हमेशा हर कॉलम को दोबारा आकार देता है; मुझे कुछ कॉलम को निश्चित चौड़ाई की अनुमति देने की आवश्यकता थी। तो इस संस्करण में "ऑटो" की चौड़ाई वाले कॉलम कॉलम ऑटो-आकार के होंगे और जो एक निश्चित राशि पर सेट होंगे वे ऑटो-आकार के नहीं होंगे।

public class AutoSizedGridView : GridView
{
    HashSet<int> _autoWidthColumns;

    protected override void PrepareItem(ListViewItem item)
    {
        if (_autoWidthColumns == null)
        {
            _autoWidthColumns = new HashSet<int>();

            foreach (var column in Columns)
            {
                if(double.IsNaN(column.Width))
                    _autoWidthColumns.Add(column.GetHashCode());
            }                
        }

        foreach (GridViewColumn column in Columns)
        {
            if (_autoWidthColumns.Contains(column.GetHashCode()))
            {
                if (double.IsNaN(column.Width))
                    column.Width = column.ActualWidth;

                column.Width = double.NaN;                    
            }          
        }

        base.PrepareItem(item);
    }        
}

2

मुझे पता है कि यह बहुत देर हो चुकी है लेकिन यहाँ मेरा दृष्टिकोण है:

<GridViewColumn x:Name="GridHeaderLocalSize"  Width="100">      
<GridViewColumn.Header>
    <GridViewColumnHeader HorizontalContentAlignment="Right">
        <Grid Width="Auto" HorizontalAlignment="Right">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Local size" TextAlignment="Right" Padding="0,0,5,0"/>
        </Grid>
    </GridViewColumnHeader>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Width="{Binding ElementName=GridHeaderLocalSize, Path=Width, FallbackValue=100}"  HorizontalAlignment="Right" TextAlignment="Right" Padding="0,0,5,0" Text="Text" >
        </TextBlock>
    </DataTemplate>
</GridViewColumn.CellTemplate>

मुख्य विचार सेलग्रीम तत्व की चौड़ाई को ViewGridColumn की चौड़ाई से बांधना है। चौड़ाई = 100 डिफ़ॉल्ट चौड़ाई है जिसका उपयोग पहले आकार बदलने तक किया जाता है। पीछे कोई कोड नहीं है। सब कुछ xaml में है।


इसने मुझे एक कॉलम की चौड़ाई भरने के लिए इस समाधान के लिए प्रेरित किया: <GridViewColumn Width = "{बाइंडिंग रिलेटिवसॉर्स = {RelativeSource AncestorType = ListView}, Path = एक्चुलाइविदथ}">
जे। एंडरसन

1

मुझे स्वीकार किए गए उत्तर से परेशानी थी (क्योंकि मैंने क्षैतिज क्षैतिज = खिंचाव वाले हिस्से को याद किया और मूल उत्तर को समायोजित किया है)।

यह एक और तकनीक है। यह एक साझाकरण समूह के साथ ग्रिड का उपयोग करता है।

ध्यान दें: Grid.IsSharedScope सच = ListView पर।

<Window x:Class="WpfApplication6.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}" Grid.IsSharedSizeScope="True">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="ID" Width="40">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                             <Grid>
                                  <Grid.ColumnDefinitions>
                                       <ColumnDefinition Width="Auto" SharedSizeGroup="IdColumn"/>
                                  </Grid.ColumnDefinitions>
                                  <TextBlock HorizontalAlignment="Right" Text={Binding Path=Id}"/>
                             </Grid>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
                <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>
</Window>

आप चौड़ाई की राशि GridViewColumnके रूप में 40और आप के लिए स्तंभ परिभाषा चौड़ाई सेट Auto? इसका कोई मतलब नहीं है।
बीके

1

मैंने एक सूची के लिए GridView कॉलम हेडर को अपडेट करने के लिए एक फ़ंक्शन बनाया और जब भी विंडो फिर से आकार या सूची के अपडेट का लेआउट होता है, तब इसे कॉल करें।

public void correctColumnWidths()
{
    double remainingSpace = myList.ActualWidth;

    if (remainingSpace > 0)
    {
         for (int i = 0; i < (myList.View as GridView).Columns.Count; i++)
              if (i != 2)
                   remainingSpace -= (myList.View as GridView).Columns[i].ActualWidth;

          //Leave 15 px free for scrollbar
          remainingSpace -= 15;

          (myList.View as GridView).Columns[2].Width = remainingSpace;
    }
}

0

यह आपका कोड है

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="40"/>
            <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="100" />
            <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
        </GridView>
    </ListView.View>
</ListView>

इसे इस्तेमाल करे

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Id}" Width="Auto">
               <GridViewColumnHeader Content="ID" Width="Auto" />
            </GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding FirstName}" Width="Auto">
              <GridViewColumnHeader Content="First Name" Width="Auto" />
            </GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding LastName}" Width="Auto">
              <GridViewColumnHeader Content="Last Name" Width="Auto" />
            </GridViewColumn
        </GridView>
    </ListView.View>
</ListView>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.