c# - 使用 Linq 和 IComparer 排序 ObservableCollection

标签 c# linq sql-order-by icomparer

我想按字母顺序对 ObservableCollection 进行排序,因为我不想创建另一个绑定(bind)。我已经看到我们可以使用 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 新手)

最佳答案

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

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

此方法有两个不同的通用参数:TSourceTKeyTSource很明显,和TSource是一样的来源IEnumerableTKey参数是编译器尝试推断但失败的参数,因为您尝试使用两种不同的类型。您的来电:

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

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

第一个参数,Func<> delegate,是“关键选择器”;这就是你所说的OrderBy排序依据的值。自从你的IComparer<>正在基于整个 GraphicObject 进行排序实例,这就是您应该选择的 key :

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

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

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

另外,请注意,您的示例代码实际上并未对新排序的列表执行任何操作,因此它只是被丢弃。 LINQ 操作从不更改源可枚举,它们总是返回它的新的、转换后的副本。

关于c# - 使用 Linq 和 IComparer 排序 ObservableCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11653862/

相关文章:

c# - 如何发送带有查询字符串的 URL 作为查询字符串

c# - IEquatable<T>.Equals 中的条件

mysql - 如何在 SQL 中按 max(a,b) 排序?

mysql - 根据条件排序 MYSQL 结果

c# - C# 中的正确函数?

c# - OnPropertyChange不会更新组合框

c# - Microsoft.AspNetCore.Identity.UserManager :Warning: User validation failed: InvalidUserName;InvalidEmail

c# - LINQ:如何使用 IQueryable() 选择特定列

c# - 如何使用 AutoMapper 将可空属性映射到 DTO?

sql - 如何使用 Magento Collections 中的表达式执行 ORDER BY