使用派生的ObservableCollection类

时间:2016-11-03 15:24:13

标签: c# derived-class

对于我的项目我需要有一个observableCollection,可以在每次添加新点时对点进行排序。 在寻找一个我在一个极好的源代码上感受到的想法之后(引用是http://www.dotmaniac.net/simple-sorted-observablecollection/。)

Idea是覆盖ObservableCollection类

中的函数
     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);
}

}

问题是我没有任何想法如何将它与我的对象一起使用。 我的对象是一个Class 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);
    }
}

}

我想使用SortedPoints类在dX属性之后添加每个新的rofpoints。

当我在代码中的某处写字时:

 SortedPoints<RofPoints> listofpoints = new SortedPoints<RofPoints>

不起作用,因为编译器无法隐式转换为IComparable。我没有任何想法如何进一步发展。你能解释一下如何使用它或给我一个例子吗?

我无法提供更多代码,因为我确实被封锁了。

2 个答案:

答案 0 :(得分:0)

您的RofPoints类必须实现IComparable<RofPoints>接口,并且必须实现方法CompareTo(RofPoints other)。所以你的课应该是这样的:

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
    }
}

答案 1 :(得分:0)

我修改了我的方法。我想在添加新值时自动对点进行排序。当我不使用MvvM模式时,SortableObservableCollection会起作用,因为它们不是事件。 SortableObservableCollection如下:

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

}

在ModelView中我尝试使用它(我不能显示所有内容,因为它是公司项目),它无法工作,因为每次在列表修改时触发事件的排序。< / p>

所以我的问题是关注如何在对列表进行排序时以及何时再次启动它时停止事件?