2009-07-31 12 views
6

मैं कैसे पूर्णांकों का कॉलम एक ListView में सॉर्टकैसे मैं इन सबसे पूर्णांकों सूचीदृश्य में

सी #, .net 2.0, Winform करते

System.Windows.Forms.ListView

+1

ASP.NET? विंडोज फॉर्म? –

+0

मैंने अपना पूरा उत्तर एक पूर्ण उदाहरण शामिल करने के लिए संपादित किया है, जो टेक्स्ट और न्यूमेरिक –

उत्तर

19

इस प्रकार मैंने कई स्तंभों को क्रमबद्ध करने में सक्षम होने और प्रत्येक कॉलम को संख्या के रूप में या पाठ के रूप में क्रमबद्ध करने में सक्षम होने के तरीके को पूरा किया।

सबसे पहले उपयोग इस वर्ग:

lvSeries.ListViewItemSorter = new Sorter(); 

फिर भी इस तरह से अपनी सूचीदृश्य नियंत्रण से ColumnClick संभाल:

class Sorter : System.Collections.IComparer 
{ 
    public int Column = 0; 
    public System.Windows.Forms.SortOrder Order = SortOrder.Ascending; 
    public int Compare(object x, object y) // IComparer Member 
    { 
     if (!(x is ListViewItem)) 
      return (0); 
     if (!(y is ListViewItem)) 
      return (0); 

     ListViewItem l1 = (ListViewItem)x; 
     ListViewItem l2 = (ListViewItem)y; 

     if (l1.ListView.Columns[Column].Tag == null) 
     { 
      l1.ListView.Columns[Column].Tag = "Text"; 
     } 

     if (l1.ListView.Columns[Column].Tag.ToString() == "Numeric") 
     { 
      float fl1 = float.Parse(l1.SubItems[Column].Text); 
      float fl2 = float.Parse(l2.SubItems[Column].Text); 

      if (Order == SortOrder.Ascending) 
      { 
       return fl1.CompareTo(fl2); 
      } 
      else 
      { 
       return fl2.CompareTo(fl1); 
      } 
     } 
     else 
     { 
      string str1 = l1.SubItems[Column].Text; 
      string str2 = l2.SubItems[Column].Text; 

      if (Order == SortOrder.Ascending) 
      { 
       return str1.CompareTo(str2); 
      } 
      else 
      { 
       return str2.CompareTo(str1); 
      } 
     } 
    } 
} 

आपके प्रपत्र के निर्माता में, इस तरह सॉर्टर सेट

private void lvSeries_ColumnClick(object sender, ColumnClickEventArgs e) 
    { 
     Sorter s = (Sorter)lvSeries.ListViewItemSorter; 
     s.Column = e.Column; 

     if (s.Order == System.Windows.Forms.SortOrder.Ascending) 
     { 
      s.Order = System.Windows.Forms.SortOrder.Descending; 
     } 
     else 
     { 
      s.Order = System.Windows.Forms.SortOrder.Ascending; 
     } 
     lvSeries.Sort(); 
    } 

यह सभी कॉलम की टैग प्रॉपर्टी पर निर्भर है या तो "न्यूम" पर सेट किया जा रहा है एरिक "या नहीं, तो सॉर्टर जानता है कि कैसे सॉर्ट करें।

उपरोक्त उदाहरण में मैंने मूल्यों को संख्याओं के रूप में फ़्लोट के रूप में डाला, जब आप इसे int में बदलना चाहते हैं।

+1

@Neil: यह उन्हें डिफ़ॉल्ट रूप से पाठ के रूप में टाइप करता है। जैसे 100 3 से पहले आता है। हालांकि, आप कस्टम ListViewItemSorter के साथ int को ठीक तरह से सॉर्ट कर सकते हैं। –

+0

आह सही है। स्ट्रिंग डिफ़ॉल्ट प्रकार है। –

+0

मैंने http://support.microsoft.com/kb/319401 पर उदाहरण का पालन किया लेकिन यह अभी भी पूर्णांक को ठीक तरह से सॉर्ट नहीं करता है। टेक्स्ट टेक्स्ट, आप सॉर्ट करने के लिए डिफ़ॉल्ट कॉलम कैसे सेट अप करते हैं। यह कॉलम 1 पर बस ठीक है लेकिन मुझे कॉलम को सॉर्ट करने के लिए सेट करने के लिए प्रॉपर्टी नहीं मिल सकती है। – Brad

0

मैं था इसे दृश्य के बजाय डेटा स्रोत (मॉडल) में करें। इसे वहां सॉर्ट करें और इसे डाटाबेसिंग के माध्यम से इसे दृश्य में अपडेट करना चाहिए।

+0

दोनों के रूप में सॉर्ट कर सकता है, आप का अर्थ है डेटासेट, मेरे उदाहरण में डेटाटेबल, और फिर कॉलम पर क्लिक होने पर सूचीदृश्य को फिर से लोड करें? – Brad

+0

नहीं, हर बार पुनः लोड करने के लिए खराब अभ्यास। Google "ListViewItemSorter" और यह आपको दिखाएगा कि प्रत्येक कॉलम द्वारा क्रमबद्ध कैसे करें। –

+0

हाँ यही मैंने सोचा था। – Brad

3

आपको एक कक्षा बनाने की आवश्यकता होगी जो IComparer इंटरफ़ेस (गैर-जेनेरिक एक) लागू करता है। उस वर्ग में आप सही उप मद से Text संपत्ति पढ़ें, यह int करने के लिए कनवर्ट करते हैं, और तुलना करें:

public class IntegerComparer : IComparer 
{ 
    private int _colIndex; 
    public IntegerComparer(int colIndex) 
    { 
     _colIndex = colIndex; 
    } 
    public int Compare(object x, object y) 
    { 
     int nx = int.Parse((x as ListViewItem).SubItems[_colIndex].Text); 
     int ny = int.Parse((y as ListViewItem).SubItems[_colIndex].Text); 
     return nx.CompareTo(ny); 
    } 
} 

तो फिर तुम ListViewItemSorter संपत्ति के लिए इस तरह के एक comparer आवंटित और ListView की तरह विधि आह्वान नियंत्रण:

// create a comparer for column index 1 and assign it to the control, and sort 
myListView.ListViewItemSorter = new IntegerComparer(1); 
myListView.Sort(); 
+0

कुछ कॉलम संख्यात्मक अन्य टेक्स्ट हैं ... क्या मुझे सॉर्टिंग से पहले संख्यात्मक के लिए परीक्षण करना चाहिए? – Brad

+1

मैंने एक बार सूची दृश्य Item तुलनाकर्ता बनाया जो प्रत्येक तत्व की जांच करता है तुलना विधि में जोड़ी, लेकिन यह धीमी हो गई। आप अलग तुलना करने वाले लोगों से अलग होना और चयन करना चाहते हैं कि किस कॉलम को सॉर्ट किया जा रहा है, या एक तुलनात्मक वर्ग बनाना जहां आप निर्माता को मान देते हैं या नहीं संख्याओं, तिथियों या पाठ के आधार पर एक प्रकार का क्रमबद्ध करने के लिए, और उस मूल्य के आधार पर तुलना विधि में स्विच करना (जो समाधान मैं उस मामले में गया था)। –

+0

अच्छा विचार। लेकिन मैंने 'sortType' जैसे एक निजी चर बनाया मेरी सूचीदृश्य के अंदर क्ला की तुलना करें इसके बजाए एसएस – Chris

5

आप एक ListView साथ शुरू हो रही है रहे हैं, तो अपने जीवन अगर आप एक ObjectListView बजाय का उपयोग बहुत ज्यादा आसान हो जाएगा। ऑब्जेक्ट लिस्ट व्यू .NET WinForms ListView के आस-पास एक ओपन सोर्स रैपर है, और यह इन सभी परेशानियों वाली छोटी समस्याओं को हल करता है जो आम तौर पर एक सूची दृश्य के साथ काम कर रहे हैं। उदाहरण के लिए, यह स्वचालित रूप से इंट्स को टाइप करता है ताकि '100' '3' के बाद आता है (डेटटाइम्स, बूल, और बाकी सबकुछ ठीक से भी प्रकार का होता है)।

गंभीरता से, आप किसी ऑब्जेक्टलिस्ट दृश्य का उपयोग करने के बाद कभी भी सादे ListView पर वापस नहीं जाना चाहेंगे।

हाँ, मैं लेखक हूं - लेकिन इसका मतलब यह नहीं है कि मैं पक्षपातपूर्ण हूं ... ठीक है, शायद यह करता है :) कुछ अन्य लोगों की राय के लिए here देखें।

+0

धन्यवाद ... इसे अभी एक परीक्षण ड्राइव देने जा रहा है – Brad

0

मैंने नील-एन की कक्षा का उपयोग किया लेकिन टैग संपत्ति के बजाय टाइप प्रॉपर्टी का परीक्षण करने के लिए अगर कथन बदल दिया। मैंने प्रत्येक कॉलम को टाइप नंबर (टेक्स्ट के बजाए) पर सेट किया है जिसमें इसमें एक पूर्णांक मान था। क्रमबद्ध काम करता है।

if (l1.ListView.Columns[Column].Type.ToString() == "Number") 
+0

मुझे यकीन नहीं है कि आपने कुछ छोड़ दिया है, लेकिन [कॉलमहेडर] (http://msdn.microsoft.com/en-us/library/system.windows .forms.columnheader.aspx) में 'टाइप' प्रॉपर्टी नहीं है। – Nick

0
class ListViewAutoSorter : System.Collections.IComparer 
{ 
    private int Column = 0; 
    private System.Windows.Forms.SortOrder Order = SortOrder.Ascending; 

    public ListViewAutoSorter(int Column, SortOrder Order) 
    { 
     this.Column = Column; 
     this.Order = Order; 
    } 

    public int Compare(object x, object y) // IComparer Member 
    { 
     if (!(x is ListViewItem)) 
      return (0); 
     if (!(y is ListViewItem)) 
      return (0); 

     var l1 = (ListViewItem)x; 
     var l2 = (ListViewItem)y; 

     var value1 = 0.0; 
     var value2 = 0.0; 

     if (Double.TryParse(l1.SubItems[Column].Text, out value1) && 
      Double.TryParse(l2.SubItems[Column].Text, out value2)) 
     { 
      if (Order == SortOrder.Ascending) 
      { 
       return value1.CompareTo(value2); 
      } 
      else 
      { 
       return value2.CompareTo(value1); 
      } 
     } 
     else 
     { 
      var str1 = l1.SubItems[Column].Text; 
      var str2 = l2.SubItems[Column].Text; 

      if (Order == SortOrder.Ascending) 
      { 
       return str1.CompareTo(str2); 
      } 
      else 
      { 
       return str2.CompareTo(str1); 
      } 
     } 
    } 
} 
संबंधित मुद्दे