2016-11-03 2 views
0

für mein Projekt Ich brauche eine observableCollection, die die Punkte jedes Mal sortieren kann, wenn wir neue Punkte hinzufügen. Nach einem Blick durch eine Idee suchen fühlte ich mich an einem herrlichen Source Code (Referenz http://www.dotmaniac.net/simple-sorted-observablecollection/.)Verwenden Sie eine abgeleitete ObservableCollection-Klasse

Die Idee ist es, die Funktionen von ObservableCollection Klasse

 public class SortedPoints<T> 
: ObservableCollection<T> where T : IComparable<T> { 

protected override void InsertItem(int index, T item) 
{ 
    if (this.Count == 0) 
    { 
     base.InsertItem(0, item); 
     return; 
    } 

    index = Compare(item, 0, this.Count - 1); 

    base.InsertItem(index, item); 
} 

private int Compare(T item, int lowIndex, int highIndex) 
{ 
    int compareIndex = (lowIndex + highIndex)/2; 

    if (compareIndex == 0) 
    { 
     return SearchIndexByIteration(lowIndex, highIndex, item); 
    } 

    int result = item.CompareTo(this[compareIndex]); 

    if (result < 0) 
    { //item precedes indexed obj in the sort order 

     if ((lowIndex + compareIndex) < 100 || compareIndex == (lowIndex + compareIndex)/2) 
     { 
      return SearchIndexByIteration(lowIndex, compareIndex, item); 
     } 

     return Compare(item, lowIndex, compareIndex); 
    } 

    if (result > 0) 
    { //item follows indexed obj in the sort order 

     if ((compareIndex + highIndex) < 100 || compareIndex == (compareIndex + highIndex)/2) 
     { 
      return SearchIndexByIteration(compareIndex, highIndex, item); 
     } 

     return Compare(item, compareIndex, highIndex); 
    } 

    return compareIndex; 
} 

/// <summary> 
/// Iterates through sequence of the collection from low to high index 
/// and returns the index where to insert the new item 
/// </summary> 
private int SearchIndexByIteration(int lowIndex, int highIndex, T item) 
{ 
    for (int i = lowIndex; i <= highIndex; i++) 
    { 
     if (item.CompareTo(this[i]) < 0) 
     { 
      return i; 
     } 
    } 
    return this.Count; 
} 

/// <summary> 
/// Adds the item to collection by ignoring the index 
/// </summary> 
protected override void SetItem(int index, T item) 
{ 
    this.InsertItem(index, item); 
} 

private const string _InsertErrorMessage 
    = "Inserting and moving an item using an explicit index are not support by sorted observable collection"; 

/// <summary> 
/// Throws an error because inserting an item using an explicit index 
/// is not support by sorted observable collection 
/// </summary> 
[Obsolete(_InsertErrorMessage)] 
public new void Insert(int index, T item) 
{ 
    throw new NotSupportedException(_InsertErrorMessage); 
} 

/// <summary> 
/// Throws an error because moving an item using explicit indexes 
/// is not support by sorted observable collection 
/// </summary> 
[Obsolete(_InsertErrorMessage)] 
public new void Move(int oldIndex, int newIndex) 
{ 
    throw new NotSupportedException(_InsertErrorMessage); 
} 

}

Das Problem außer Kraft zu setzen ist Ich habe keine Idee, wie ich es mit meinen Objekten verwenden soll. Meine Objekte ist eine Klasse RofPoints

public class RofPoints : IComparable 
{ 
    [DisplayName("X")] 
    [Description("Punkte der X axis")] 
    public int X { get; set; } 
    [DisplayName("Y")] 
    [Description("Punkte auf der Y Achse")] 
    public int Y { get; set; } 
    private double dx; 
    [DisplayName("dX")] 
    [Description("Punkte auf der X Achse mit double values")] 
    public double dX 
    { 
     get 
     { 
      return dx; 
     } 

     set 
     { 
      dx = value; 
     } 
    } 

    private double dy; 
    [DisplayName("dY")] 
    [Description("Punkte auf der Y Achse mit double values")] 
    public double dY 
    { 
     get 
     { 
      return dy; 
     } 
     set 
     { 
      dy = value; 
     } 
    } 
    public override string ToString() 
    { 
     return X + "/" + Y; 
    } 

    public double CompareTo(double dX) 
    { 
     return this.dX; 
    } 

    public int CompareTo(object obj) 
    { 
     return dx.CompareTo(obj); 
    } 
} 

}

Ich mag würde die SortedPoints Klasse verwenden alle neuen rofpoints haben nach dem dX Attribut bestellt hinzugefügt.

Wenn ich schreibe irgendwo im Code:

SortedPoints<RofPoints> listofpoints = new SortedPoints<RofPoints> 

, die nicht da funktioniert der Compiler implizit IComparable nicht konvertieren kann. Ich habe keine Ahnung, wie ich weiter kommen soll. Kannst du mir erklären, wie man es benutzt oder mir ein Beispiel gibt?

Ich kann nicht mehr Code geben, weil ich wirklich blockiert bin.

Antwort

0

Ihre Klasse RofPoints muss die Schnittstelle IComparable<RofPoints> implementieren, und Sie müssen die Methode CompareTo(RofPoints other) implementieren. Ihre Klasse sollte also etwa so aussehen:

public class RofPoints : IComparable<RofPoints> 
{ 
    [DisplayName("X")] 
    [Description("Punkte der X axis")] 
    public int X { get; set; } 
    [DisplayName("Y")] 
    [Description("Punkte auf der Y Achse")] 
    public int Y { get; set; } 
    private double dx; 
    [DisplayName("dX")] 
    [Description("Punkte auf der X Achse mit double values")] 
    public double dX 
    { 
     get 
     { 
      return dx; 
     } 

     set 
     { 
      dx = value; 
     } 
    } 

    private double dy; 
    [DisplayName("dY")] 
    [Description("Punkte auf der Y Achse mit double values")] 
    public double dY 
    { 
     get 
     { 
      return dy; 
     } 
     set 
     { 
      dy = value; 
     } 
    } 

    public int CompareTo(RofPoints other) 
    { 
     //Here you must compare a RofPoints object to another 
    } 
} 
+0

Vielen Dank für die Antwort. Ich habe versucht, die Compare-Methode in der RofPoints-Klasse zu implementieren, aber es ändert nichts. – littlecloud47

+0

Die 'CompareTo' Methode von' RofPoints' muss -1.0 oder 1 zurückliefern, abhängig davon, welches Objekt größer ist. Also müssen Sie zuerst erklären, wenn ein 'RofPoints'-Objekt größer als das andere ist (ist es größer, wenn X größer ist, wenn Y größer ist, abhängig von einer Funktion auf diesen 2 Werten ....?) – Pikoh

0

Ich habe meine Vorgehensweise geändert. Ich wollte die Punkte beim Hinzufügen neuer Werte automatisch sortieren. Die SortiereObservableCollection funktioniert, wenn ich das MvvM-Muster nicht verwende, da sie keine Ereignisse sind. Die SortableObservableCollection ist wie folgt:

public class SortableObservableCollection<T> : ObservableCollection<T> 
{ 
    public void Sort<TKey>(Func<T, TKey> keySelector, System.ComponentModel.ListSortDirection direction) 
    { 
     switch (direction) 
     { 
      case System.ComponentModel.ListSortDirection.Ascending: 
       { 
        ApplySort(Items.OrderBy(keySelector)); 
        break; 
       } 
      case System.ComponentModel.ListSortDirection.Descending: 
       { 
        ApplySort(Items.OrderByDescending(keySelector)); 
        break; 
       } 
     } 
    } 

    public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer) 
    { 
     ApplySort(Items.OrderBy(keySelector, comparer)); 
    } 

    private void ApplySort(IEnumerable<T> sortedItems) 
    { 
     var sortedItemsList = sortedItems.ToList(); 

     foreach (var item in sortedItemsList) 
     { 
      Move(IndexOf(item), sortedItemsList.IndexOf(item)); 
     } 
    } 
} 

}

In den Modelview Ich versuche, es zu benutzen (ich alles nicht anzeigen kann, weil es sich um ein Unternehmen Projekt ist), kann es nicht, weil die Art arbeiten Jedes Mal, wenn Ereignisse ausgelöst werden, wenn die Liste geändert wird.

Also meine Frage folgt Wie ist es möglich, das Ereignis beim Sortieren der Liste zu stoppen und wenn es wieder gestartet wird?

Verwandte Themen