ListView Sortierung



  • Bin grad am verzweifeln, weil mir das Rückwärts-sortieren einfach nicht gelingt.
    Hoff Ihr könnt mir helfen:

    Hier mal ein Programm-Ausschnitt:

    IComparer-Implementierung:

    ref class ListViewItemComparer: public System::Collections::IComparer
    {
    private:
        int col;
    
        public:
        ListViewItemComparer() { col = 0; }
        ListViewItemComparer( int column ) { col = column; }
    
        virtual int Compare( Object^ x, Object^ y )
        {
            return String::Compare( (dynamic_cast<ListViewItem^>(x))->SubItems[col]->Text, (dynamic_cast<ListViewItem^>(y))->SubItems[col]->Text );
        }
    };
    

    Über ein ColumnClick-Event rufe ich folgende Methode auf:

    private: System::Void ZumTesten_ColumnClick(System::Object^  sender, System::Windows::Forms::ColumnClickEventArgs^  e) 
    {
        if( this->ZumTesten->Sorting == SortOrder::Ascending )
        this->ZumTesten->Sorting = SortOrder::Descending;
        else this->ZumTesten->Sorting = SortOrder::Ascending;
    
        this->ZumTesten->ListViewItemSorter = gcnew ListViewItemComparer( e->Column );
    }
    

    Alles wunderbar, Liste wird sortiert.
    Leider aber eben immer nur "aufwärts"-sortiert, also Ascending !!!
    Komme einfach nicht auf die Lösung!

    Habe auch schon versucht mittels einer static-Variable festzustellen, ob die selbe Sparte geklickt wurde als die zuvor und wenn das der Fall sein sollte, dass dann der Comparer aufgerufen wird, ansonst wechselt er nur die "Sorting"-Eigenschaft und ruft Sort() auf. Geht aber auch nicht.

    Nur eins hilft: In der IComparer-Implementierung in der return-Zeile x und y vertauschen!
    Das muss doch aber auch mittels der Sorting-Eigenschaft funktionieren oder?
    Zumindest habe ich das auf den msdn-Seiten gelesen!

    Kann einer helfen?

    Grüße
    Stefan



  • Habe ich in der Klasse gemacht:

    public ref class numberColumn:System::Collections::IComparer{
    
    private:
    	Int32 aktSpalte;	
    	Int32 sortRichtung;
    
    public:
    	numberColumn(Int32 spalte,Int32 richtung){
    		aktSpalte=spalte;
    		sortRichtung=richtung;
    	}	
    	virtual Int32 Compare(System::Object ^x,System::Object ^y){	
    
    			Int32 ergebnis;
    
    Vielleicht hilft Dir das.
    			Int32 zahl1,zahl2;
    
    			ListViewItem ^ersterEintrag=dynamic_cast<ListViewItem^>(x);
    			ListViewItem ^zweiterEintrag=dynamic_cast<ListViewItem^>(y);
    
    			zahl1=Convert::ToInt32(ersterEintrag->SubItems[aktSpalte]->Text);
    
    			zahl2=Convert::ToInt32(zweiterEintrag->SubItems[aktSpalte]->Text);
    
    			if(zahl1<zahl2)
    				ergebnis=-1;
    
    			if(sortRichtung==0)
    				return ergebnis;
    			else
    				return -ergebnis;
    
    	}			
    
    };
    

    Aufruf:

    numberColumn ^columnSort=gcnew numberColumn(2,listViewSortDirection);
    				listView->ListViewItemSorter=columnSort;
    				listView->Sort();
    


  • Uups, "Vielleicht hilft Dir das." gehört da nicht hin, sollte eigenltich ganz unten stehen.



  • Hallo,
    Du müsstest Dir noch die aktuelle Sortierung merken und den Rückgabewert dann entsprechend ändern. Ich tippe mal was aus dem Bauch raus zusammen ....

    ref class ListViewItemComparer: public System::Collections::IComparer
    {
    
    public:
        SortOrder Sortierung;
    
    private:
        int col;
    
        public:
        ListViewItemComparer() { col = 0;    Sortierung=SortOrder::Ascending;}
        ListViewItemComparer( int column ) { col = column; }
    
        virtual int Compare( Object^ x, Object^ y )
        {
            int nCmp =  String::Compare( (dynamic_cast<ListViewItem^>(x))->SubItems[col]->Text, (dynamic_cast<ListViewItem^>(y))->SubItems[col]->Text );
    
            if ( Sortierung == SortOrder::Ascending)
               return nCmp;
            else
               return -nCmp;
    
        }
    

    Gruß
    foodax



  • Vielen Dank Jungs, habe nun folgende Lösung genommen:

    ref class ListViewItemComparer: public System::Collections::IComparer
    	{
    	private:
    		int _col;
    		SortOrder _so;
    
    	public:
    		ListViewItemComparer() { _col = 0; _so = SortOrder::Ascending; }
    		ListViewItemComparer( int column ) { _col = column; _so = SortOrder::Ascending; }
    		ListViewItemComparer( SortOrder sortorder ) { _col = 0; _so = sortorder; }
    		ListViewItemComparer( int column, SortOrder sortorder ) { _col = column; _so = sortorder; }
    
    		virtual int Compare( Object^ x, Object^ y )
    		{		  
    			if( _so == SortOrder::None ) return 0;
    			int nCmp = String::Compare( (dynamic_cast<ListViewItem^>(x))->SubItems[col]->Text,
    				(dynamic_cast<ListViewItem^>(y))->SubItems[col]->Text );
    			if( _so == SortOrder::Descending ) return -nCmp;
    			return nCmp;
    		}
    	};
    


  • Hallo Culan,

    Culan schrieb:

    Vielen Dank Jungs, habe nun folgende Lösung genommen:

    Fehlt da nicht noch eine Methode um _so von dem Clickhandler aus zu ändern?

    Gruß
    foodax



  • Hast Recht foodax, hab deine Nachricht leider erst jetzt gelesen.

    Hier nochmal das komplette Objekt:

    ref class ListViewItemComparer: public System::Collections::IComparer
    	{
    	private:
    		int _col;
    		SortOrder _so;
    
    	public:
    		ListViewItemComparer() { this->_col = 0; this->_so = SortOrder::Ascending; }
    		ListViewItemComparer( int column ) { this->_col = column; this->_so = SortOrder::Ascending; }
    		ListViewItemComparer( SortOrder sortorder ) { this->_col = 0; this->_so = sortorder; }
    		ListViewItemComparer( int column, SortOrder sortorder ) { this->_col = column; this->_so = sortorder; }
    
    		virtual int Compare( Object^ x, Object^ y )
    		{		  
    			if( this->_so == SortOrder::None ) return 0;
    			if( ( x == nullptr ) || ( y == nullptr ) ) return 0;
    			int nCmp = String::Compare( (dynamic_cast<ListViewItem^>(x))->SubItems[this->_col]->Text,
    				(dynamic_cast<ListViewItem^>(y))->SubItems[this->_col]->Text );
    			if( this->_so == SortOrder::Descending ) return -nCmp;
    			return nCmp;
    		}
    	};
    

Anmelden zum Antworten