2

我想按字母顺序排列 ObservableCollection,因为我不想创建另一个绑定。我已经看到我们可以使用 Linq 和 OrderBy 方法。我还想使用个人 IComparer 因为我将不得不组织复杂的数据(列表到其他列表中),但是 VS 告诉我我不能使用我自己的比较器:

(给你错误的链接,因为我的VS是法语的)

http://msdn.microsoft.com/en-gb/library/hxfhx4sy%28v=vs.90%29.aspx

有任何想法吗 ?

private void SortGraphicObjectsAscending(object sender, RoutedEventArgs e)
    {
        GraphicObjects.OrderBy(graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

    }

还有我自己的比较器(已经过测试)

public class GraphicObjectComparer : IComparer<GraphicObject>
{
    int order = 1;

    public GraphicObjectComparer(Boolean ascending)
    {
        if (!ascending)
        {
            order = -1;
        }
    }

    public GraphicObjectComparer()
    {

    }

    public int Compare(GraphicObject x, GraphicObject y)
    {
        return String.Compare(x.Nom, y.Nom, false) * order;
    }

}

感谢您的回答。无论如何,我还有另一个问题。正如迈克尔所说,我使用了一个更复杂的比较器,但用于另一个实体。该实体以分层树的形式显示,并且一个对象可能包含相同类型的其他对象的列表。

我无法测试我的 GraphicObject,因为我无权访问数据库(目前没有对象)。通过对我的 VideoEntity 的测试,我的 ObservableCollection 似乎没有按照我想要的方式排序(我创建了另一个)。我想按字母顺序颠倒它,但它不起作用。

public class VideoEntityComparer : IComparer<VideoEntity>
{

    int order = 1;

    public VideoEntityComparer(Boolean ascending)
    {
        if (!ascending)
        {
            this.order = -1; // so descending
        }
    }

    public VideoEntityComparer()
    {

    }

    public int Compare(VideoEntity x, VideoEntity y)
    {
        if ((x is BaseDirectory && y is BaseDirectory) || (x is BaseSite && y is BaseSite) || (x is VideoEncoder && y is VideoEncoder))
        {
            return string.Compare(x.Nom, y.Nom, false) * order; // only objects of the same type are sorted alphabetically
        }
        else if ((x is BaseDirectory && y is BaseSite) || (x is BaseSite && y is VideoEncoder))
        {
            return -1;
        }else
        {
            return 1;
        }
    }
}

private void SortDirectoriesDescending(object sender, RoutedEventArgs e)
    {
        ObservableCollection<BaseDirectory> tempDir  = new ObservableCollection<BaseDirectory>(
            Directories.OrderBy(directory => directory, new VideoEntityComparer(false)));
        Directories = tempDir;
    }

PS:顺便说一句,我正在处理一个 DependancyProperty。这是正确的方法吗?(我是 WPF 的新手)

4

4 回答 4

3

该行的问题OrderBy在于您尝试使用的定义:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer
)

此方法有两个不同的通用参数:TSourceTKey. TSource很明显,它与TSourcesource相同IEnumerable。该TKey参数是编译器尝试并失败的参数,因为您尝试使用两种不同的类型。你的来电:

GraphicObjects.OrderBy(graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

您的第一个参数是 aFunc<GraphicObject, string>但您的第二个参数是 a IComparer<GraphicObject>; 这意味着您TKey = string在一个地方和另一个地方使用TKey = GraphicObject

第一个参数,Func<>委托,是“键选择器”;这就是您如何判断OrderBy要排序的值的方式。由于您IComparer<>是根据整个GraphicObject实例进行排序的,因此您应该选择它作为键:

GraphicObjects.OrderBy(go => go, new GraphicObjectComparer(true));

我假设您的自定义比较器对象实际上比您显示的更复杂,因为您的示例比较器非常多余:

var asc = GraphicObjects.OrderBy(go => go.Nom);
var desc = GraphicObjects.OrderByDescending(go => go.Nom);

另外,请注意,您的示例代码实际上并没有对新排序的列表做任何事情,所以它只是被扔掉了。LINQ 操作永远不会更改源可枚举,它们总是返回一个新的、转换后的副本。

于 2012-07-25T16:21:07.547 回答
1

你的comparer比较GraphicObject。所以你OrderBy应该是

 GraphicObjects.OrderBy(graphicObject => graphicObject,
                                                 new GraphicObjectComparer(true));

或者只是使用

GraphicObjects.OrderBy(graphicObject => graphicObject.Nom);

顺便说一句,OrderBy不会就地排序,您应该将返回的值分配IEnumerable<GraphicsObject>给变量

于 2012-07-25T16:20:33.523 回答
0

问题是您的比较器使用的是 GraphicObject,但您比较的是字符串。

如果您确实需要自己订购,可以使用此比较器:

public class GraphicObjectComparer : IComparer<string>
{
    int order = 1;

    public GraphicObjectComparer(Boolean ascending)
    {
        if (!ascending)
        {
            order = -1;
        }
    }

    public GraphicObjectComparer()
    {

    }

    public int Compare(string x, string y)
    {
        return String.Compare(x, y, false) * order;
    }
}

或者,您向比较器提供 GraphicObject,而不是字符串。

于 2012-07-25T16:24:04.037 回答
0

为了排序 ObservableCollection 反映源集合中的所有更改,您可以使用我的ObservableComputations库。使用这个库,您可以像这样编写代码:

var sortedGraphicObjects = GraphicObjects.Ordering(
    graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

sortedGraphicObjects 是 ObservableCollection,反映了 GraphicObjects 集合和 Nom 属性的所有变化。确保 Nom 属性通过INotifyPropertyChanged接口通知更改。

于 2019-11-19T12:36:55.133 回答